diff options
Diffstat (limited to 'drivers/block/drbd/drbd_actlog.c')
-rw-r--r-- | drivers/block/drbd/drbd_actlog.c | 259 |
1 files changed, 0 insertions, 259 deletions
diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c index 58b5b61..da8ffd5 100644 --- a/drivers/block/drbd/drbd_actlog.c +++ b/drivers/block/drbd/drbd_actlog.c @@ -462,265 +462,6 @@ w_al_write_transaction(struct drbd_work *w, int unused) return 0; } -/* FIXME - * reading of the activity log, - * and potentially dirtying of the affected bitmap regions, - * should be done from userland only. - * DRBD would simply always attach with an empty activity log, - * and refuse to attach to something that looks like a crashed primary. - */ - -/** - * drbd_al_read_tr() - Read a single transaction from the on disk activity log - * @mdev: DRBD device. - * @bdev: Block device to read form. - * @b: pointer to an al_transaction. - * @index: On disk slot of the transaction to read. - * - * Returns -1 on IO error, 0 on checksum error and 1 upon success. - */ -static int drbd_al_read_tr(struct drbd_conf *mdev, - struct drbd_backing_dev *bdev, - int index) -{ - struct al_transaction_on_disk *b = page_address(mdev->md_io_page); - sector_t sector; - u32 crc; - - sector = bdev->md.md_offset - + bdev->md.al_offset - + index * (MD_BLOCK_SIZE>>9); - - /* Dont process error normally, - * as this is done before disk is attached! */ - if (drbd_md_sync_page_io(mdev, bdev, sector, READ)) - return -1; - - if (!expect(b->magic == cpu_to_be32(DRBD_AL_MAGIC))) - return 0; - - if (!expect(be16_to_cpu(b->n_updates) <= AL_UPDATES_PER_TRANSACTION)) - return 0; - - if (!expect(be16_to_cpu(b->context_size) <= DRBD_AL_EXTENTS_MAX)) - return 0; - - if (!expect(be16_to_cpu(b->context_start_slot_nr) < DRBD_AL_EXTENTS_MAX)) - return 0; - - crc = be32_to_cpu(b->crc32c); - b->crc32c = 0; - if (!expect(crc == crc32c(0, b, 4096))) - return 0; - - return 1; -} - -/** - * drbd_al_read_log() - Restores the activity log from its on disk representation. - * @mdev: DRBD device. - * @bdev: Block device to read form. - * - * Returns 1 on success, returns 0 when reading the log failed due to IO errors. - */ -int drbd_al_read_log(struct drbd_conf *mdev, struct drbd_backing_dev *bdev) -{ - struct al_transaction_on_disk *b; - int i; - int rv; - int mx; - int active_extents = 0; - int transactions = 0; - int found_valid = 0; - int found_initialized = 0; - int from = 0; - int to = 0; - u32 from_tnr = 0; - u32 to_tnr = 0; - u32 cnr; - - /* Note that this is expected to be called with a newly created, - * clean and all unused activity log of the "expected size". - */ - - /* lock out all other meta data io for now, - * and make sure the page is mapped. - */ - b = drbd_md_get_buffer(mdev); - if (!b) - return 0; - - /* Always use the full ringbuffer space for now. - * possible optimization: read in all of it, - * then scan the in-memory pages. */ - - mx = (MD_AL_SECTORS*512/MD_BLOCK_SIZE); - - /* Find the valid transaction in the log */ - for (i = 0; i < mx; i++) { - rv = drbd_al_read_tr(mdev, bdev, i); - /* invalid data in that block */ - if (rv == 0) - continue; - if (be16_to_cpu(b->transaction_type) == AL_TR_INITIALIZED) { - ++found_initialized; - continue; - } - - /* IO error */ - if (rv == -1) { - drbd_md_put_buffer(mdev); - return 0; - } - - cnr = be32_to_cpu(b->tr_number); - if (++found_valid == 1) { - from = i; - to = i; - from_tnr = cnr; - to_tnr = cnr; - continue; - } - - D_ASSERT(cnr != to_tnr); - D_ASSERT(cnr != from_tnr); - if ((int)cnr - (int)from_tnr < 0) { - D_ASSERT(from_tnr - cnr + i - from == mx); - from = i; - from_tnr = cnr; - } - if ((int)cnr - (int)to_tnr > 0) { - D_ASSERT(cnr - to_tnr == i - to); - to = i; - to_tnr = cnr; - } - } - - if (!found_valid) { - if (found_initialized != mx) - dev_warn(DEV, "No usable activity log found.\n"); - drbd_md_put_buffer(mdev); - return 1; - } - - /* Read the valid transactions. - * dev_info(DEV, "Reading from %d to %d.\n",from,to); */ - i = from; - while (1) { - struct lc_element *e; - unsigned j, n, slot, extent_nr; - - rv = drbd_al_read_tr(mdev, bdev, i); - if (!expect(rv != 0)) - goto cancel; - if (rv == -1) { - drbd_md_put_buffer(mdev); - return 0; - } - - /* deal with different transaction types. - * not yet implemented */ - if (!expect(b->transaction_type == 0)) - goto cancel; - - /* on the fly re-create/resize activity log? - * will be a special transaction type flag. */ - if (!expect(be16_to_cpu(b->context_size) == mdev->act_log->nr_elements)) - goto cancel; - if (!expect(be16_to_cpu(b->context_start_slot_nr) < mdev->act_log->nr_elements)) - goto cancel; - - /* We are the only user of the activity log right now, - * don't actually need to take that lock. */ - spin_lock_irq(&mdev->al_lock); - - /* first, apply the context, ... */ - for (j = 0, slot = be16_to_cpu(b->context_start_slot_nr); - j < AL_CONTEXT_PER_TRANSACTION && - slot < mdev->act_log->nr_elements; j++, slot++) { - extent_nr = be32_to_cpu(b->context[j]); - e = lc_element_by_index(mdev->act_log, slot); - if (e->lc_number != extent_nr) { - if (extent_nr != LC_FREE) - active_extents++; - else - active_extents--; - } - lc_set(mdev->act_log, extent_nr, slot); - } - - /* ... then apply the updates, - * which override the context information. - * drbd_al_read_tr already did the rangecheck - * on n <= AL_UPDATES_PER_TRANSACTION */ - n = be16_to_cpu(b->n_updates); - for (j = 0; j < n; j++) { - slot = be16_to_cpu(b->update_slot_nr[j]); - extent_nr = be32_to_cpu(b->update_extent_nr[j]); - if (!expect(slot < mdev->act_log->nr_elements)) - break; - e = lc_element_by_index(mdev->act_log, slot); - if (e->lc_number != extent_nr) { - if (extent_nr != LC_FREE) - active_extents++; - else - active_extents--; - } - lc_set(mdev->act_log, extent_nr, slot); - } - spin_unlock_irq(&mdev->al_lock); - - transactions++; - -cancel: - if (i == to) - break; - i++; - if (i >= mx) - i = 0; - } - - mdev->al_tr_number = to_tnr+1; - mdev->al_tr_pos = (to + 1) % (MD_AL_SECTORS*512/MD_BLOCK_SIZE); - - /* ok, we are done with it */ - drbd_md_put_buffer(mdev); - - dev_info(DEV, "Found %d transactions (%d active extents) in activity log.\n", - transactions, active_extents); - - return 1; -} - -/** - * drbd_al_apply_to_bm() - Sets the bitmap to dirty(1) where covered by active AL extents - * @mdev: DRBD device. - */ -void drbd_al_apply_to_bm(struct drbd_conf *mdev) -{ - unsigned int enr; - unsigned long add = 0; - char ppb[10]; - int i, tmp; - - wait_event(mdev->al_wait, lc_try_lock(mdev->act_log)); - - for (i = 0; i < mdev->act_log->nr_elements; i++) { - enr = lc_element_by_index(mdev->act_log, i)->lc_number; - if (enr == LC_FREE) - continue; - tmp = drbd_bm_ALe_set_all(mdev, enr); - dynamic_dev_dbg(DEV, "AL: set %d bits in extent %u\n", tmp, enr); - add += tmp; - } - - lc_unlock(mdev->act_log); - wake_up(&mdev->al_wait); - - dev_info(DEV, "Marked additional %s as out-of-sync based on AL.\n", - ppsize(ppb, Bit2KB(add))); -} - static int _try_lc_del(struct drbd_conf *mdev, struct lc_element *al_ext) { int rv; |