dm thin metadata: use pool locking at end of dm_pool_metadata_close
[linux-2.6-microblaze.git] / drivers / md / dm-thin-metadata.c
index b88d6d7..fc9947d 100644 (file)
@@ -28,7 +28,7 @@
  *
  * - A hierarchical btree, with 2 levels which effectively maps (thin
  *   dev id, virtual block) -> block_time.  Block time is a 64-bit
- *   field holding the time in the low 24 bits, and block in the top 48
+ *   field holding the time in the low 24 bits, and block in the top 40
  *   bits.
  *
  * BTrees consist solely of btree_nodes, that fill a block.  Some are
@@ -387,16 +387,15 @@ static int subtree_equal(void *context, const void *value1_le, const void *value
  * Variant that is used for in-core only changes or code that
  * shouldn't put the pool in service on its own (e.g. commit).
  */
-static inline void __pmd_write_lock(struct dm_pool_metadata *pmd)
+static inline void pmd_write_lock_in_core(struct dm_pool_metadata *pmd)
        __acquires(pmd->root_lock)
 {
        down_write(&pmd->root_lock);
 }
-#define pmd_write_lock_in_core(pmd) __pmd_write_lock((pmd))
 
 static inline void pmd_write_lock(struct dm_pool_metadata *pmd)
 {
-       __pmd_write_lock(pmd);
+       pmd_write_lock_in_core(pmd);
        if (unlikely(!pmd->in_service))
                pmd->in_service = true;
 }
@@ -811,7 +810,7 @@ static int __write_changed_details(struct dm_pool_metadata *pmd)
                        return r;
 
                if (td->open_count)
-                       td->changed = 0;
+                       td->changed = false;
                else {
                        list_del(&td->list);
                        kfree(td);
@@ -831,6 +830,7 @@ static int __commit_transaction(struct dm_pool_metadata *pmd)
         * We need to know if the thin_disk_superblock exceeds a 512-byte sector.
         */
        BUILD_BUG_ON(sizeof(struct thin_disk_superblock) > 512);
+       BUG_ON(!rwsem_is_locked(&pmd->root_lock));
 
        if (unlikely(!pmd->in_service))
                return 0;
@@ -953,6 +953,7 @@ int dm_pool_metadata_close(struct dm_pool_metadata *pmd)
                return -EBUSY;
        }
 
+       pmd_write_lock_in_core(pmd);
        if (!dm_bm_is_read_only(pmd->bm) && !pmd->fail_io) {
                r = __commit_transaction(pmd);
                if (r < 0)
@@ -961,6 +962,7 @@ int dm_pool_metadata_close(struct dm_pool_metadata *pmd)
        }
        if (!pmd->fail_io)
                __destroy_persistent_data_objects(pmd);
+       pmd_write_unlock(pmd);
 
        kfree(pmd);
        return 0;
@@ -1106,7 +1108,7 @@ static int __set_snapshot_details(struct dm_pool_metadata *pmd,
        if (r)
                return r;
 
-       td->changed = 1;
+       td->changed = true;
        td->snapshotted_time = time;
 
        snap->mapped_blocks = td->mapped_blocks;
@@ -1618,7 +1620,7 @@ static int __insert(struct dm_thin_device *td, dm_block_t block,
        if (r)
                return r;
 
-       td->changed = 1;
+       td->changed = true;
        if (inserted)
                td->mapped_blocks++;
 
@@ -1649,7 +1651,7 @@ static int __remove(struct dm_thin_device *td, dm_block_t block)
                return r;
 
        td->mapped_blocks--;
-       td->changed = 1;
+       td->changed = true;
 
        return 0;
 }
@@ -1703,7 +1705,7 @@ static int __remove_range(struct dm_thin_device *td, dm_block_t begin, dm_block_
        }
 
        td->mapped_blocks -= total_count;
-       td->changed = 1;
+       td->changed = true;
 
        /*
         * Reinsert the mapping tree.
@@ -1841,7 +1843,7 @@ int dm_pool_commit_metadata(struct dm_pool_metadata *pmd)
         * Care is taken to not have commit be what
         * triggers putting the thin-pool in-service.
         */
-       __pmd_write_lock(pmd);
+       pmd_write_lock_in_core(pmd);
        if (pmd->fail_io)
                goto out;