aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS6
-rw-r--r--drivers/block/drbd/drbd_actlog.c104
-rw-r--r--drivers/block/drbd/drbd_bitmap.c146
-rw-r--r--drivers/block/drbd/drbd_int.h90
-rw-r--r--drivers/block/drbd/drbd_main.c357
-rw-r--r--drivers/block/drbd/drbd_nl.c48
-rw-r--r--drivers/block/drbd/drbd_proc.c2
-rw-r--r--drivers/block/drbd/drbd_receiver.c95
-rw-r--r--drivers/block/drbd/drbd_req.c132
-rw-r--r--drivers/block/drbd/drbd_req.h19
-rw-r--r--drivers/block/drbd/drbd_worker.c31
-rw-r--r--drivers/block/floppy.c161
-rw-r--r--drivers/block/xen-blkfront.c44
-rw-r--r--include/linux/drbd.h6
-rw-r--r--include/linux/drbd_limits.h7
-rw-r--r--include/linux/drbd_nl.h5
16 files changed, 862 insertions, 391 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index a246490c95eb..64e675d6d478 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2818,6 +2818,12 @@ F: Documentation/firmware_class/
2818F: drivers/base/firmware*.c 2818F: drivers/base/firmware*.c
2819F: include/linux/firmware.h 2819F: include/linux/firmware.h
2820 2820
2821FLOPPY DRIVER
2822M: Jiri Kosina <jkosina@suse.cz>
2823T: git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/floppy.git
2824S: Odd fixes
2825F: drivers/block/floppy.c
2826
2821FPU EMULATOR 2827FPU EMULATOR
2822M: Bill Metzenthen <billm@melbpc.org.au> 2828M: Bill Metzenthen <billm@melbpc.org.au>
2823W: http://floatingpoint.sourceforge.net/emulator/index.html 2829W: http://floatingpoint.sourceforge.net/emulator/index.html
diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c
index cf0e63dd97da..e54e31b02b88 100644
--- a/drivers/block/drbd/drbd_actlog.c
+++ b/drivers/block/drbd/drbd_actlog.c
@@ -65,39 +65,80 @@ struct drbd_atodb_wait {
65 65
66int w_al_write_transaction(struct drbd_conf *, struct drbd_work *, int); 66int w_al_write_transaction(struct drbd_conf *, struct drbd_work *, int);
67 67
68void *drbd_md_get_buffer(struct drbd_conf *mdev)
69{
70 int r;
71
72 wait_event(mdev->misc_wait,
73 (r = atomic_cmpxchg(&mdev->md_io_in_use, 0, 1)) == 0 ||
74 mdev->state.disk <= D_FAILED);
75
76 return r ? NULL : page_address(mdev->md_io_page);
77}
78
79void drbd_md_put_buffer(struct drbd_conf *mdev)
80{
81 if (atomic_dec_and_test(&mdev->md_io_in_use))
82 wake_up(&mdev->misc_wait);
83}
84
85static bool md_io_allowed(struct drbd_conf *mdev)
86{
87 enum drbd_disk_state ds = mdev->state.disk;
88 return ds >= D_NEGOTIATING || ds == D_ATTACHING;
89}
90
91void wait_until_done_or_disk_failure(struct drbd_conf *mdev, struct drbd_backing_dev *bdev,
92 unsigned int *done)
93{
94 long dt = bdev->dc.disk_timeout * HZ / 10;
95 if (dt == 0)
96 dt = MAX_SCHEDULE_TIMEOUT;
97
98 dt = wait_event_timeout(mdev->misc_wait, *done || !md_io_allowed(mdev), dt);
99 if (dt == 0)
100 dev_err(DEV, "meta-data IO operation timed out\n");
101}
102
68static int _drbd_md_sync_page_io(struct drbd_conf *mdev, 103static int _drbd_md_sync_page_io(struct drbd_conf *mdev,
69 struct drbd_backing_dev *bdev, 104 struct drbd_backing_dev *bdev,
70 struct page *page, sector_t sector, 105 struct page *page, sector_t sector,
71 int rw, int size) 106 int rw, int size)
72{ 107{
73 struct bio *bio; 108 struct bio *bio;
74 struct drbd_md_io md_io;
75 int ok; 109 int ok;
76 110
77 md_io.mdev = mdev; 111 mdev->md_io.done = 0;
78 init_completion(&md_io.event); 112 mdev->md_io.error = -ENODEV;
79 md_io.error = 0;
80 113
81 if ((rw & WRITE) && !test_bit(MD_NO_FUA, &mdev->flags)) 114 if ((rw & WRITE) && !test_bit(MD_NO_FUA, &mdev->flags))
82 rw |= REQ_FUA | REQ_FLUSH; 115 rw |= REQ_FUA | REQ_FLUSH;
83 rw |= REQ_SYNC; 116 rw |= REQ_SYNC;
84 117
85 bio = bio_alloc(GFP_NOIO, 1); 118 bio = bio_alloc_drbd(GFP_NOIO);
86 bio->bi_bdev = bdev->md_bdev; 119 bio->bi_bdev = bdev->md_bdev;
87 bio->bi_sector = sector; 120 bio->bi_sector = sector;
88 ok = (bio_add_page(bio, page, size, 0) == size); 121 ok = (bio_add_page(bio, page, size, 0) == size);
89 if (!ok) 122 if (!ok)
90 goto out; 123 goto out;
91 bio->bi_private = &md_io; 124 bio->bi_private = &mdev->md_io;
92 bio->bi_end_io = drbd_md_io_complete; 125 bio->bi_end_io = drbd_md_io_complete;
93 bio->bi_rw = rw; 126 bio->bi_rw = rw;
94 127
128 if (!get_ldev_if_state(mdev, D_ATTACHING)) { /* Corresponding put_ldev in drbd_md_io_complete() */
129 dev_err(DEV, "ASSERT FAILED: get_ldev_if_state() == 1 in _drbd_md_sync_page_io()\n");
130 ok = 0;
131 goto out;
132 }
133
134 bio_get(bio); /* one bio_put() is in the completion handler */
135 atomic_inc(&mdev->md_io_in_use); /* drbd_md_put_buffer() is in the completion handler */
95 if (drbd_insert_fault(mdev, (rw & WRITE) ? DRBD_FAULT_MD_WR : DRBD_FAULT_MD_RD)) 136 if (drbd_insert_fault(mdev, (rw & WRITE) ? DRBD_FAULT_MD_WR : DRBD_FAULT_MD_RD))
96 bio_endio(bio, -EIO); 137 bio_endio(bio, -EIO);
97 else 138 else
98 submit_bio(rw, bio); 139 submit_bio(rw, bio);
99 wait_for_completion(&md_io.event); 140 wait_until_done_or_disk_failure(mdev, bdev, &mdev->md_io.done);
100 ok = bio_flagged(bio, BIO_UPTODATE) && md_io.error == 0; 141 ok = bio_flagged(bio, BIO_UPTODATE) && mdev->md_io.error == 0;
101 142
102 out: 143 out:
103 bio_put(bio); 144 bio_put(bio);
@@ -111,7 +152,7 @@ int drbd_md_sync_page_io(struct drbd_conf *mdev, struct drbd_backing_dev *bdev,
111 int offset = 0; 152 int offset = 0;
112 struct page *iop = mdev->md_io_page; 153 struct page *iop = mdev->md_io_page;
113 154
114 D_ASSERT(mutex_is_locked(&mdev->md_io_mutex)); 155 D_ASSERT(atomic_read(&mdev->md_io_in_use) == 1);
115 156
116 BUG_ON(!bdev->md_bdev); 157 BUG_ON(!bdev->md_bdev);
117 158
@@ -328,8 +369,13 @@ w_al_write_transaction(struct drbd_conf *mdev, struct drbd_work *w, int unused)
328 return 1; 369 return 1;
329 } 370 }
330 371
331 mutex_lock(&mdev->md_io_mutex); /* protects md_io_buffer, al_tr_cycle, ... */ 372 buffer = drbd_md_get_buffer(mdev); /* protects md_io_buffer, al_tr_cycle, ... */
332 buffer = (struct al_transaction *)page_address(mdev->md_io_page); 373 if (!buffer) {
374 dev_err(DEV, "disk failed while waiting for md_io buffer\n");
375 complete(&((struct update_al_work *)w)->event);
376 put_ldev(mdev);
377 return 1;
378 }
333 379
334 buffer->magic = __constant_cpu_to_be32(DRBD_MAGIC); 380 buffer->magic = __constant_cpu_to_be32(DRBD_MAGIC);
335 buffer->tr_number = cpu_to_be32(mdev->al_tr_number); 381 buffer->tr_number = cpu_to_be32(mdev->al_tr_number);
@@ -374,7 +420,7 @@ w_al_write_transaction(struct drbd_conf *mdev, struct drbd_work *w, int unused)
374 D_ASSERT(mdev->al_tr_pos < MD_AL_MAX_SIZE); 420 D_ASSERT(mdev->al_tr_pos < MD_AL_MAX_SIZE);
375 mdev->al_tr_number++; 421 mdev->al_tr_number++;
376 422
377 mutex_unlock(&mdev->md_io_mutex); 423 drbd_md_put_buffer(mdev);
378 424
379 complete(&((struct update_al_work *)w)->event); 425 complete(&((struct update_al_work *)w)->event);
380 put_ldev(mdev); 426 put_ldev(mdev);
@@ -443,8 +489,9 @@ int drbd_al_read_log(struct drbd_conf *mdev, struct drbd_backing_dev *bdev)
443 /* lock out all other meta data io for now, 489 /* lock out all other meta data io for now,
444 * and make sure the page is mapped. 490 * and make sure the page is mapped.
445 */ 491 */
446 mutex_lock(&mdev->md_io_mutex); 492 buffer = drbd_md_get_buffer(mdev);
447 buffer = page_address(mdev->md_io_page); 493