@@ -192,6 +192,13 @@ struct dm_pool_metadata {
192
192
* operation possible in this state is the closing of the device.
193
193
*/
194
194
bool fail_io :1 ;
195
+
196
+ /*
197
+ * Reading the space map roots can fail, so we read it into these
198
+ * buffers before the superblock is locked and updated.
199
+ */
200
+ __u8 data_space_map_root [SPACE_MAP_ROOT_SIZE ];
201
+ __u8 metadata_space_map_root [SPACE_MAP_ROOT_SIZE ];
195
202
};
196
203
197
204
struct dm_thin_device {
@@ -431,26 +438,53 @@ static void __setup_btree_details(struct dm_pool_metadata *pmd)
431
438
pmd -> details_info .value_type .equal = NULL ;
432
439
}
433
440
441
+ static int save_sm_roots (struct dm_pool_metadata * pmd )
442
+ {
443
+ int r ;
444
+ size_t len ;
445
+
446
+ r = dm_sm_root_size (pmd -> metadata_sm , & len );
447
+ if (r < 0 )
448
+ return r ;
449
+
450
+ r = dm_sm_copy_root (pmd -> metadata_sm , & pmd -> metadata_space_map_root , len );
451
+ if (r < 0 )
452
+ return r ;
453
+
454
+ r = dm_sm_root_size (pmd -> data_sm , & len );
455
+ if (r < 0 )
456
+ return r ;
457
+
458
+ return dm_sm_copy_root (pmd -> data_sm , & pmd -> data_space_map_root , len );
459
+ }
460
+
461
+ static void copy_sm_roots (struct dm_pool_metadata * pmd ,
462
+ struct thin_disk_superblock * disk )
463
+ {
464
+ memcpy (& disk -> metadata_space_map_root ,
465
+ & pmd -> metadata_space_map_root ,
466
+ sizeof (pmd -> metadata_space_map_root ));
467
+
468
+ memcpy (& disk -> data_space_map_root ,
469
+ & pmd -> data_space_map_root ,
470
+ sizeof (pmd -> data_space_map_root ));
471
+ }
472
+
434
473
static int __write_initial_superblock (struct dm_pool_metadata * pmd )
435
474
{
436
475
int r ;
437
476
struct dm_block * sblock ;
438
- size_t metadata_len , data_len ;
439
477
struct thin_disk_superblock * disk_super ;
440
478
sector_t bdev_size = i_size_read (pmd -> bdev -> bd_inode ) >> SECTOR_SHIFT ;
441
479
442
480
if (bdev_size > THIN_METADATA_MAX_SECTORS )
443
481
bdev_size = THIN_METADATA_MAX_SECTORS ;
444
482
445
- r = dm_sm_root_size (pmd -> metadata_sm , & metadata_len );
446
- if (r < 0 )
447
- return r ;
448
-
449
- r = dm_sm_root_size (pmd -> data_sm , & data_len );
483
+ r = dm_sm_commit (pmd -> data_sm );
450
484
if (r < 0 )
451
485
return r ;
452
486
453
- r = dm_sm_commit (pmd -> data_sm );
487
+ r = save_sm_roots (pmd );
454
488
if (r < 0 )
455
489
return r ;
456
490
@@ -471,15 +505,7 @@ static int __write_initial_superblock(struct dm_pool_metadata *pmd)
471
505
disk_super -> trans_id = 0 ;
472
506
disk_super -> held_root = 0 ;
473
507
474
- r = dm_sm_copy_root (pmd -> metadata_sm , & disk_super -> metadata_space_map_root ,
475
- metadata_len );
476
- if (r < 0 )
477
- goto bad_locked ;
478
-
479
- r = dm_sm_copy_root (pmd -> data_sm , & disk_super -> data_space_map_root ,
480
- data_len );
481
- if (r < 0 )
482
- goto bad_locked ;
508
+ copy_sm_roots (pmd , disk_super );
483
509
484
510
disk_super -> data_mapping_root = cpu_to_le64 (pmd -> root );
485
511
disk_super -> device_details_root = cpu_to_le64 (pmd -> details_root );
@@ -488,10 +514,6 @@ static int __write_initial_superblock(struct dm_pool_metadata *pmd)
488
514
disk_super -> data_block_size = cpu_to_le32 (pmd -> data_block_size );
489
515
490
516
return dm_tm_commit (pmd -> tm , sblock );
491
-
492
- bad_locked :
493
- dm_bm_unlock (sblock );
494
- return r ;
495
517
}
496
518
497
519
static int __format_metadata (struct dm_pool_metadata * pmd )
@@ -769,6 +791,10 @@ static int __commit_transaction(struct dm_pool_metadata *pmd)
769
791
if (r < 0 )
770
792
return r ;
771
793
794
+ r = save_sm_roots (pmd );
795
+ if (r < 0 )
796
+ return r ;
797
+
772
798
r = superblock_lock (pmd , & sblock );
773
799
if (r )
774
800
return r ;
@@ -780,21 +806,9 @@ static int __commit_transaction(struct dm_pool_metadata *pmd)
780
806
disk_super -> trans_id = cpu_to_le64 (pmd -> trans_id );
781
807
disk_super -> flags = cpu_to_le32 (pmd -> flags );
782
808
783
- r = dm_sm_copy_root (pmd -> metadata_sm , & disk_super -> metadata_space_map_root ,
784
- metadata_len );
785
- if (r < 0 )
786
- goto out_locked ;
787
-
788
- r = dm_sm_copy_root (pmd -> data_sm , & disk_super -> data_space_map_root ,
789
- data_len );
790
- if (r < 0 )
791
- goto out_locked ;
809
+ copy_sm_roots (pmd , disk_super );
792
810
793
811
return dm_tm_commit (pmd -> tm , sblock );
794
-
795
- out_locked :
796
- dm_bm_unlock (sblock );
797
- return r ;
798
812
}
799
813
800
814
struct dm_pool_metadata * dm_pool_metadata_open (struct block_device * bdev ,
0 commit comments