diff options
| -rw-r--r-- | MAINTAINERS | 6 | ||||
| -rw-r--r-- | drivers/block/drbd/drbd_actlog.c | 104 | ||||
| -rw-r--r-- | drivers/block/drbd/drbd_bitmap.c | 146 | ||||
| -rw-r--r-- | drivers/block/drbd/drbd_int.h | 90 | ||||
| -rw-r--r-- | drivers/block/drbd/drbd_main.c | 357 | ||||
| -rw-r--r-- | drivers/block/drbd/drbd_nl.c | 48 | ||||
| -rw-r--r-- | drivers/block/drbd/drbd_proc.c | 2 | ||||
| -rw-r--r-- | drivers/block/drbd/drbd_receiver.c | 95 | ||||
| -rw-r--r-- | drivers/block/drbd/drbd_req.c | 132 | ||||
| -rw-r--r-- | drivers/block/drbd/drbd_req.h | 19 | ||||
| -rw-r--r-- | drivers/block/drbd/drbd_worker.c | 31 | ||||
| -rw-r--r-- | drivers/block/floppy.c | 161 | ||||
| -rw-r--r-- | drivers/block/xen-blkfront.c | 44 | ||||
| -rw-r--r-- | include/linux/drbd.h | 6 | ||||
| -rw-r--r-- | include/linux/drbd_limits.h | 7 | ||||
| -rw-r--r-- | include/linux/drbd_nl.h | 5 |
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/ | |||
| 2818 | F: drivers/base/firmware*.c | 2818 | F: drivers/base/firmware*.c |
| 2819 | F: include/linux/firmware.h | 2819 | F: include/linux/firmware.h |
| 2820 | 2820 | ||
| 2821 | FLOPPY DRIVER | ||
| 2822 | M: Jiri Kosina <jkosina@suse.cz> | ||
| 2823 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/floppy.git | ||
| 2824 | S: Odd fixes | ||
| 2825 | F: drivers/block/floppy.c | ||
| 2826 | |||
| 2821 | FPU EMULATOR | 2827 | FPU EMULATOR |
| 2822 | M: Bill Metzenthen <billm@melbpc.org.au> | 2828 | M: Bill Metzenthen <billm@melbpc.org.au> |
| 2823 | W: http://floatingpoint.sourceforge.net/emulator/index.html | 2829 | W: 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 | ||
| 66 | int w_al_write_transaction(struct drbd_conf *, struct drbd_work *, int); | 66 | int w_al_write_transaction(struct drbd_conf *, struct drbd_work *, int); |
| 67 | 67 | ||
| 68 | void *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 | |||
| 79 | void 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 | |||
| 85 | static 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 | |||
| 91 | void 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 | |||
| 68 | static int _drbd_md_sync_page_io(struct drbd_conf *mdev, | 103 | static 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 | |
