aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/persistent-data/dm-block-manager.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/persistent-data/dm-block-manager.c')
-rw-r--r--drivers/md/persistent-data/dm-block-manager.c105
1 files changed, 59 insertions, 46 deletions
diff --git a/drivers/md/persistent-data/dm-block-manager.c b/drivers/md/persistent-data/dm-block-manager.c
index 0317ecdc6e53..5ba277768d99 100644
--- a/drivers/md/persistent-data/dm-block-manager.c
+++ b/drivers/md/persistent-data/dm-block-manager.c
@@ -325,11 +325,6 @@ static struct dm_buffer *to_buffer(struct dm_block *b)
325 return (struct dm_buffer *) b; 325 return (struct dm_buffer *) b;
326} 326}
327 327
328static struct dm_bufio_client *to_bufio(struct dm_block_manager *bm)
329{
330 return (struct dm_bufio_client *) bm;
331}
332
333dm_block_t dm_block_location(struct dm_block *b) 328dm_block_t dm_block_location(struct dm_block *b)
334{ 329{
335 return dm_bufio_get_block_number(to_buffer(b)); 330 return dm_bufio_get_block_number(to_buffer(b));
@@ -367,34 +362,60 @@ static void dm_block_manager_write_callback(struct dm_buffer *buf)
367/*---------------------------------------------------------------- 362/*----------------------------------------------------------------
368 * Public interface 363 * Public interface
369 *--------------------------------------------------------------*/ 364 *--------------------------------------------------------------*/
365struct dm_block_manager {
366 struct dm_bufio_client *bufio;
367 bool read_only:1;
368};
369
370struct dm_block_manager *dm_block_manager_create(struct block_device *bdev, 370struct dm_block_manager *dm_block_manager_create(struct block_device *bdev,
371 unsigned block_size, 371 unsigned block_size,
372 unsigned cache_size, 372 unsigned cache_size,
373 unsigned max_held_per_thread) 373 unsigned max_held_per_thread)
374{ 374{
375 return (struct dm_block_manager *) 375 int r;
376 dm_bufio_client_create(bdev, block_size, max_held_per_thread, 376 struct dm_block_manager *bm;
377 sizeof(struct buffer_aux), 377
378 dm_block_manager_alloc_callback, 378 bm = kmalloc(sizeof(*bm), GFP_KERNEL);
379 dm_block_manager_write_callback); 379 if (!bm) {
380 r = -ENOMEM;
381 goto bad;
382 }
383
384 bm->bufio = dm_bufio_client_create(bdev, block_size, max_held_per_thread,
385 sizeof(struct buffer_aux),
386 dm_block_manager_alloc_callback,
387 dm_block_manager_write_callback);
388 if (IS_ERR(bm->bufio)) {
389 r = PTR_ERR(bm->bufio);
390 kfree(bm);
391 goto bad;
392 }
393
394 bm->read_only = false;
395
396 return bm;
397
398bad:
399 return ERR_PTR(r);
380} 400}
381EXPORT_SYMBOL_GPL(dm_block_manager_create); 401EXPORT_SYMBOL_GPL(dm_block_manager_create);
382 402
383void dm_block_manager_destroy(struct dm_block_manager *bm) 403void dm_block_manager_destroy(struct dm_block_manager *bm)
384{ 404{
385 return dm_bufio_client_destroy(to_bufio(bm)); 405 dm_bufio_client_destroy(bm->bufio);
406 kfree(bm);
386} 407}
387EXPORT_SYMBOL_GPL(dm_block_manager_destroy); 408EXPORT_SYMBOL_GPL(dm_block_manager_destroy);
388 409
389unsigned dm_bm_block_size(struct dm_block_manager *bm) 410unsigned dm_bm_block_size(struct dm_block_manager *bm)
390{ 411{
391 return dm_bufio_get_block_size(to_bufio(bm)); 412 return dm_bufio_get_block_size(bm->bufio);
392} 413}
393EXPORT_SYMBOL_GPL(dm_bm_block_size); 414EXPORT_SYMBOL_GPL(dm_bm_block_size);
394 415
395dm_block_t dm_bm_nr_blocks(struct dm_block_manager *bm) 416dm_block_t dm_bm_nr_blocks(struct dm_block_manager *bm)
396{ 417{
397 return dm_bufio_get_device_size(to_bufio(bm)); 418 return dm_bufio_get_device_size(bm->bufio);
398} 419}
399 420
400static int dm_bm_validate_buffer(struct dm_block_manager *bm, 421static int dm_bm_validate_buffer(struct dm_block_manager *bm,
@@ -406,7 +427,7 @@ static int dm_bm_validate_buffer(struct dm_block_manager *bm,
406 int r; 427 int r;
407 if (!v) 428 if (!v)
408 return 0; 429 return 0;
409 r = v->check(v, (struct dm_block *) buf, dm_bufio_get_block_size(to_bufio(bm))); 430 r = v->check(v, (struct dm_block *) buf, dm_bufio_get_block_size(bm->bufio));
410 if (unlikely(r)) 431 if (unlikely(r))
411 return r; 432 return r;
412 aux->validator = v; 433 aux->validator = v;
@@ -430,7 +451,7 @@ int dm_bm_read_lock(struct dm_block_manager *bm, dm_block_t b,
430 void *p; 451 void *p;
431 int r; 452 int r;
432 453
433 p = dm_bufio_read(to_bufio(bm), b, (struct dm_buffer **) result); 454 p = dm_bufio_read(bm->bufio, b, (struct dm_buffer **) result);
434 if (unlikely(IS_ERR(p))) 455 if (unlikely(IS_ERR(p)))
435 return PTR_ERR(p); 456 return PTR_ERR(p);
436 457
@@ -463,7 +484,10 @@ int dm_bm_write_lock(struct dm_block_manager *bm,
463 void *p; 484 void *p;
464 int r; 485 int r;
465 486
466 p = dm_bufio_read(to_bufio(bm), b, (struct dm_buffer **) result); 487 if (bm->read_only)
488 return -EPERM;
489
490 p = dm_bufio_read(bm->bufio, b, (struct dm_buffer **) result);
467 if (unlikely(IS_ERR(p))) 491 if (unlikely(IS_ERR(p)))
468 return PTR_ERR(p); 492 return PTR_ERR(p);
469 493
@@ -496,7 +520,7 @@ int dm_bm_read_try_lock(struct dm_block_manager *bm,
496 void *p; 520 void *p;
497 int r; 521 int r;
498 522
499 p = dm_bufio_get(to_bufio(bm), b, (struct dm_buffer **) result); 523 p = dm_bufio_get(bm->bufio, b, (struct dm_buffer **) result);
500 if (unlikely(IS_ERR(p))) 524 if (unlikely(IS_ERR(p)))
501 return PTR_ERR(p); 525 return PTR_ERR(p);
502 if (unlikely(!p)) 526 if (unlikely(!p))
@@ -529,7 +553,10 @@ int dm_bm_write_lock_zero(struct dm_block_manager *bm,
529 struct buffer_aux *aux; 553 struct buffer_aux *aux;
530 void *p; 554 void *p;
531 555
532 p = dm_bufio_new(to_bufio(bm), b, (struct dm_buffer **) result); 556 if (bm->read_only)
557 return -EPERM;
558
559 p = dm_bufio_new(bm->bufio, b, (struct dm_buffer **) result);
533 if (unlikely(IS_ERR(p))) 560 if (unlikely(IS_ERR(p)))
534 return PTR_ERR(p); 561 return PTR_ERR(p);
535 562
@@ -547,6 +574,7 @@ int dm_bm_write_lock_zero(struct dm_block_manager *bm,
547 574
548 return 0; 575 return 0;
549} 576}
577EXPORT_SYMBOL_GPL(dm_bm_write_lock_zero);
550 578
551int dm_bm_unlock(struct dm_block *b) 579int dm_bm_unlock(struct dm_block *b)
552{ 580{
@@ -565,45 +593,30 @@ int dm_bm_unlock(struct dm_block *b)
565} 593}
566EXPORT_SYMBOL_GPL(dm_bm_unlock); 594EXPORT_SYMBOL_GPL(dm_bm_unlock);
567 595
568int dm_bm_unlock_move(struct dm_block *b, dm_block_t n)
569{
570 struct buffer_aux *aux;
571
572 aux = dm_bufio_get_aux_data(to_buffer(b));
573
574 if (aux->write_locked) {
575 dm_bufio_mark_buffer_dirty(to_buffer(b));
576 bl_up_write(&aux->lock);
577 } else
578 bl_up_read(&aux->lock);
579
580 dm_bufio_release_move(to_buffer(b), n);
581 return 0;
582}
583
584int dm_bm_flush_and_unlock(struct dm_block_manager *bm, 596int dm_bm_flush_and_unlock(struct dm_block_manager *bm,
585 struct dm_block *superblock) 597 struct dm_block *superblock)
586{ 598{
587 int r; 599 int r;
588 600
589 r = dm_bufio_write_dirty_buffers(to_bufio(bm)); 601 if (bm->read_only)
590 if (unlikely(r)) 602 return -EPERM;
591 return r; 603
592 r = dm_bufio_issue_flush(to_bufio(bm)); 604 r = dm_bufio_write_dirty_buffers(bm->bufio);
593 if (unlikely(r)) 605 if (unlikely(r)) {
606 dm_bm_unlock(superblock);
594 return r; 607 return r;
608 }
595 609
596 dm_bm_unlock(superblock); 610 dm_bm_unlock(superblock);
597 611
598 r = dm_bufio_write_dirty_buffers(to_bufio(bm)); 612 return dm_bufio_write_dirty_buffers(bm->bufio);
599 if (unlikely(r)) 613}
600 return r;
601 r = dm_bufio_issue_flush(to_bufio(bm));
602 if (unlikely(r))
603 return r;
604 614
605 return 0; 615void dm_bm_set_read_only(struct dm_block_manager *bm)
616{
617 bm->read_only = true;
606} 618}
619EXPORT_SYMBOL_GPL(dm_bm_set_read_only);
607 620
608u32 dm_bm_checksum(const void *data, size_t len, u32 init_xor) 621u32 dm_bm_checksum(const void *data, size_t len, u32 init_xor)
609{ 622{