aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/drbd/drbd_req.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block/drbd/drbd_req.h')
-rw-r--r--drivers/block/drbd/drbd_req.h187
1 files changed, 69 insertions, 118 deletions
diff --git a/drivers/block/drbd/drbd_req.h b/drivers/block/drbd/drbd_req.h
index 3d2111919486..016de6b8bb57 100644
--- a/drivers/block/drbd/drbd_req.h
+++ b/drivers/block/drbd/drbd_req.h
@@ -77,40 +77,41 @@
77 */ 77 */
78 78
79enum drbd_req_event { 79enum drbd_req_event {
80 created, 80 CREATED,
81 to_be_send, 81 TO_BE_SENT,
82 to_be_submitted, 82 TO_BE_SUBMITTED,
83 83
84 /* XXX yes, now I am inconsistent... 84 /* XXX yes, now I am inconsistent...
85 * these are not "events" but "actions" 85 * these are not "events" but "actions"
86 * oh, well... */ 86 * oh, well... */
87 queue_for_net_write, 87 QUEUE_FOR_NET_WRITE,
88 queue_for_net_read, 88 QUEUE_FOR_NET_READ,
89 queue_for_send_oos, 89 QUEUE_FOR_SEND_OOS,
90 90
91 send_canceled, 91 SEND_CANCELED,
92 send_failed, 92 SEND_FAILED,
93 handed_over_to_network, 93 HANDED_OVER_TO_NETWORK,
94 oos_handed_to_network, 94 OOS_HANDED_TO_NETWORK,
95 connection_lost_while_pending, 95 CONNECTION_LOST_WHILE_PENDING,
96 read_retry_remote_canceled, 96 READ_RETRY_REMOTE_CANCELED,
97 recv_acked_by_peer, 97 RECV_ACKED_BY_PEER,
98 write_acked_by_peer, 98 WRITE_ACKED_BY_PEER,
99 write_acked_by_peer_and_sis, /* and set_in_sync */ 99 WRITE_ACKED_BY_PEER_AND_SIS, /* and set_in_sync */
100 conflict_discarded_by_peer, 100 CONFLICT_RESOLVED,
101 neg_acked, 101 POSTPONE_WRITE,
102 barrier_acked, /* in protocol A and B */ 102 NEG_ACKED,
103 data_received, /* (remote read) */ 103 BARRIER_ACKED, /* in protocol A and B */
104 104 DATA_RECEIVED, /* (remote read) */
105 read_completed_with_error, 105
106 read_ahead_completed_with_error, 106 READ_COMPLETED_WITH_ERROR,
107 write_completed_with_error, 107 READ_AHEAD_COMPLETED_WITH_ERROR,
108 abort_disk_io, 108 WRITE_COMPLETED_WITH_ERROR,
109 completed_ok, 109 ABORT_DISK_IO,
110 resend, 110 COMPLETED_OK,
111 fail_frozen_disk_io, 111 RESEND,
112 restart_frozen_disk_io, 112 FAIL_FROZEN_DISK_IO,
113 nothing, /* for tracing only */ 113 RESTART_FROZEN_DISK_IO,
114 NOTHING,
114}; 115};
115 116
116/* encoding of request states for now. we don't actually need that many bits. 117/* encoding of request states for now. we don't actually need that many bits.
@@ -142,8 +143,8 @@ enum drbd_req_state_bits {
142 * recv_ack (B) or implicit "ack" (A), 143 * recv_ack (B) or implicit "ack" (A),
143 * still waiting for the barrier ack. 144 * still waiting for the barrier ack.
144 * master_bio may already be completed and invalidated. 145 * master_bio may already be completed and invalidated.
145 * 11100: write_acked (C), 146 * 11100: write acked (C),
146 * data_received (for remote read, any protocol) 147 * data received (for remote read, any protocol)
147 * or finally the barrier ack has arrived (B,A)... 148 * or finally the barrier ack has arrived (B,A)...
148 * request can be freed 149 * request can be freed
149 * 01100: neg-acked (write, protocol C) 150 * 01100: neg-acked (write, protocol C)
@@ -198,6 +199,22 @@ enum drbd_req_state_bits {
198 199
199 /* Should call drbd_al_complete_io() for this request... */ 200 /* Should call drbd_al_complete_io() for this request... */
200 __RQ_IN_ACT_LOG, 201 __RQ_IN_ACT_LOG,
202
203 /* The peer has sent a retry ACK */
204 __RQ_POSTPONED,
205
206 /* would have been completed,
207 * but was not, because of drbd_suspended() */
208 __RQ_COMPLETION_SUSP,
209
210 /* We expect a receive ACK (wire proto B) */
211 __RQ_EXP_RECEIVE_ACK,
212
213 /* We expect a write ACK (wite proto C) */
214 __RQ_EXP_WRITE_ACK,
215
216 /* waiting for a barrier ack, did an extra kref_get */
217 __RQ_EXP_BARR_ACK,
201}; 218};
202 219
203#define RQ_LOCAL_PENDING (1UL << __RQ_LOCAL_PENDING) 220#define RQ_LOCAL_PENDING (1UL << __RQ_LOCAL_PENDING)
@@ -219,56 +236,16 @@ enum drbd_req_state_bits {
219 236
220#define RQ_WRITE (1UL << __RQ_WRITE) 237#define RQ_WRITE (1UL << __RQ_WRITE)
221#define RQ_IN_ACT_LOG (1UL << __RQ_IN_ACT_LOG) 238#define RQ_IN_ACT_LOG (1UL << __RQ_IN_ACT_LOG)
239#define RQ_POSTPONED (1UL << __RQ_POSTPONED)
240#define RQ_COMPLETION_SUSP (1UL << __RQ_COMPLETION_SUSP)
241#define RQ_EXP_RECEIVE_ACK (1UL << __RQ_EXP_RECEIVE_ACK)
242#define RQ_EXP_WRITE_ACK (1UL << __RQ_EXP_WRITE_ACK)
243#define RQ_EXP_BARR_ACK (1UL << __RQ_EXP_BARR_ACK)
222 244
223/* For waking up the frozen transfer log mod_req() has to return if the request 245/* For waking up the frozen transfer log mod_req() has to return if the request
224 should be counted in the epoch object*/ 246 should be counted in the epoch object*/
225#define MR_WRITE_SHIFT 0 247#define MR_WRITE 1
226#define MR_WRITE (1 << MR_WRITE_SHIFT) 248#define MR_READ 2
227#define MR_READ_SHIFT 1
228#define MR_READ (1 << MR_READ_SHIFT)
229
230/* epoch entries */
231static inline
232struct hlist_head *ee_hash_slot(struct drbd_conf *mdev, sector_t sector)
233{
234 BUG_ON(mdev->ee_hash_s == 0);
235 return mdev->ee_hash +
236 ((unsigned int)(sector>>HT_SHIFT) % mdev->ee_hash_s);
237}
238
239/* transfer log (drbd_request objects) */
240static inline
241struct hlist_head *tl_hash_slot(struct drbd_conf *mdev, sector_t sector)
242{
243 BUG_ON(mdev->tl_hash_s == 0);
244 return mdev->tl_hash +
245 ((unsigned int)(sector>>HT_SHIFT) % mdev->tl_hash_s);
246}
247
248/* application reads (drbd_request objects) */
249static struct hlist_head *ar_hash_slot(struct drbd_conf *mdev, sector_t sector)
250{
251 return mdev->app_reads_hash
252 + ((unsigned int)(sector) % APP_R_HSIZE);
253}
254
255/* when we receive the answer for a read request,
256 * verify that we actually know about it */
257static inline struct drbd_request *_ar_id_to_req(struct drbd_conf *mdev,
258 u64 id, sector_t sector)
259{
260 struct hlist_head *slot = ar_hash_slot(mdev, sector);
261 struct hlist_node *n;
262 struct drbd_request *req;
263
264 hlist_for_each_entry(req, n, slot, collision) {
265 if ((unsigned long)req == (unsigned long)id) {
266 D_ASSERT(req->sector == sector);
267 return req;
268 }
269 }
270 return NULL;
271}
272 249
273static inline void drbd_req_make_private_bio(struct drbd_request *req, struct bio *bio_src) 250static inline void drbd_req_make_private_bio(struct drbd_request *req, struct bio *bio_src)
274{ 251{
@@ -278,41 +255,10 @@ static inline void drbd_req_make_private_bio(struct drbd_request *req, struct bi
278 req->private_bio = bio; 255 req->private_bio = bio;
279 256
280 bio->bi_private = req; 257 bio->bi_private = req;
281 bio->bi_end_io = drbd_endio_pri; 258 bio->bi_end_io = drbd_request_endio;
282 bio->bi_next = NULL; 259 bio->bi_next = NULL;
283} 260}
284 261
285static inline struct drbd_request *drbd_req_new(struct drbd_conf *mdev,
286 struct bio *bio_src)
287{
288 struct drbd_request *req =
289 mempool_alloc(drbd_request_mempool, GFP_NOIO);
290 if (likely(req)) {
291 drbd_req_make_private_bio(req, bio_src);
292
293 req->rq_state = bio_data_dir(bio_src) == WRITE ? RQ_WRITE : 0;
294 req->mdev = mdev;
295 req->master_bio = bio_src;
296 req->epoch = 0;
297 req->sector = bio_src->bi_sector;
298 req->size = bio_src->bi_size;
299 INIT_HLIST_NODE(&req->collision);
300 INIT_LIST_HEAD(&req->tl_requests);
301 INIT_LIST_HEAD(&req->w.list);
302 }
303 return req;
304}
305
306static inline void drbd_req_free(struct drbd_request *req)
307{
308 mempool_free(req, drbd_request_mempool);
309}
310
311static inline int overlaps(sector_t s1, int l1, sector_t s2, int l2)
312{
313 return !((s1 + (l1>>9) <= s2) || (s1 >= s2 + (l2>>9)));
314}
315
316/* Short lived temporary struct on the stack. 262/* Short lived temporary struct on the stack.
317 * We could squirrel the error to be returned into 263 * We could squirrel the error to be returned into
318 * bio->bi_size, or similar. But that would be too ugly. */ 264 * bio->bi_size, or similar. But that would be too ugly. */
@@ -321,6 +267,7 @@ struct bio_and_error {
321 int error; 267 int error;
322}; 268};
323 269
270extern void drbd_req_destroy(struct kref *kref);
324extern void _req_may_be_done(struct drbd_request *req, 271extern void _req_may_be_done(struct drbd_request *req,
325 struct bio_and_error *m); 272 struct bio_and_error *m);
326extern int __req_mod(struct drbd_request *req, enum drbd_req_event what, 273extern int __req_mod(struct drbd_request *req, enum drbd_req_event what,
@@ -328,13 +275,17 @@ extern int __req_mod(struct drbd_request *req, enum drbd_req_event what,
328extern void complete_master_bio(struct drbd_conf *mdev, 275extern void complete_master_bio(struct drbd_conf *mdev,
329 struct bio_and_error *m); 276 struct bio_and_error *m);
330extern void request_timer_fn(unsigned long data); 277extern void request_timer_fn(unsigned long data);
331extern void tl_restart(struct drbd_conf *mdev, enum drbd_req_event what); 278extern void tl_restart(struct drbd_tconn *tconn, enum drbd_req_event what);
279extern void _tl_restart(struct drbd_tconn *tconn, enum drbd_req_event what);
280
281/* this is in drbd_main.c */
282extern void drbd_restart_request(struct drbd_request *req);
332 283
333/* use this if you don't want to deal with calling complete_master_bio() 284/* use this if you don't want to deal with calling complete_master_bio()
334 * outside the spinlock, e.g. when walking some list on cleanup. */ 285 * outside the spinlock, e.g. when walking some list on cleanup. */
335static inline int _req_mod(struct drbd_request *req, enum drbd_req_event what) 286static inline int _req_mod(struct drbd_request *req, enum drbd_req_event what)
336{ 287{
337 struct drbd_conf *mdev = req->mdev; 288 struct drbd_conf *mdev = req->w.mdev;
338 struct bio_and_error m; 289 struct bio_and_error m;
339 int rv; 290 int rv;
340 291
@@ -354,13 +305,13 @@ static inline int req_mod(struct drbd_request *req,
354 enum drbd_req_event what) 305 enum drbd_req_event what)
355{ 306{
356 unsigned long flags; 307 unsigned long flags;
357 struct drbd_conf *mdev = req->mdev; 308 struct drbd_conf *mdev = req->w.mdev;
358 struct bio_and_error m; 309 struct bio_and_error m;
359 int rv; 310 int rv;
360 311
361 spin_lock_irqsave(&mdev->req_lock, flags); 312 spin_lock_irqsave(&mdev->tconn->req_lock, flags);
362 rv = __req_mod(req, what, &m); 313 rv = __req_mod(req, what, &m);
363 spin_unlock_irqrestore(&mdev->req_lock, flags); 314 spin_unlock_irqrestore(&mdev->tconn->req_lock, flags);
364 315
365 if (m.bio) 316 if (m.bio)
366 complete_master_bio(mdev, &m); 317 complete_master_bio(mdev, &m);
@@ -368,7 +319,7 @@ static inline int req_mod(struct drbd_request *req,
368 return rv; 319 return rv;
369} 320}
370 321
371static inline bool drbd_should_do_remote(union drbd_state s) 322static inline bool drbd_should_do_remote(union drbd_dev_state s)
372{ 323{
373 return s.pdsk == D_UP_TO_DATE || 324 return s.pdsk == D_UP_TO_DATE ||
374 (s.pdsk >= D_INCONSISTENT && 325 (s.pdsk >= D_INCONSISTENT &&
@@ -378,7 +329,7 @@ static inline bool drbd_should_do_remote(union drbd_state s)
378 That is equivalent since before 96 IO was frozen in the C_WF_BITMAP* 329 That is equivalent since before 96 IO was frozen in the C_WF_BITMAP*
379 states. */ 330 states. */
380} 331}
381static inline bool drbd_should_send_oos(union drbd_state s) 332static inline bool drbd_should_send_out_of_sync(union drbd_dev_state s)
382{ 333{
383 return s.conn == C_AHEAD || s.conn == C_WF_BITMAP_S; 334 return s.conn == C_AHEAD || s.conn == C_WF_BITMAP_S;
384 /* pdsk = D_INCONSISTENT as a consequence. Protocol 96 check not necessary 335 /* pdsk = D_INCONSISTENT as a consequence. Protocol 96 check not necessary