Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright (C) 2010-2011 Red Hat, Inc.
0003  *
0004  * This file is released under the GPL.
0005  */
0006 
0007 #ifndef DM_THIN_METADATA_H
0008 #define DM_THIN_METADATA_H
0009 
0010 #include "persistent-data/dm-block-manager.h"
0011 #include "persistent-data/dm-space-map.h"
0012 #include "persistent-data/dm-space-map-metadata.h"
0013 
0014 #define THIN_METADATA_BLOCK_SIZE DM_SM_METADATA_BLOCK_SIZE
0015 
0016 /*
0017  * The metadata device is currently limited in size.
0018  */
0019 #define THIN_METADATA_MAX_SECTORS DM_SM_METADATA_MAX_SECTORS
0020 
0021 /*
0022  * A metadata device larger than 16GB triggers a warning.
0023  */
0024 #define THIN_METADATA_MAX_SECTORS_WARNING (16 * (1024 * 1024 * 1024 >> SECTOR_SHIFT))
0025 
0026 /*----------------------------------------------------------------*/
0027 
0028 /*
0029  * Thin metadata superblock flags.
0030  */
0031 #define THIN_METADATA_NEEDS_CHECK_FLAG (1 << 0)
0032 
0033 struct dm_pool_metadata;
0034 struct dm_thin_device;
0035 
0036 /*
0037  * Device identifier
0038  */
0039 typedef uint64_t dm_thin_id;
0040 
0041 /*
0042  * Reopens or creates a new, empty metadata volume.
0043  */
0044 struct dm_pool_metadata *dm_pool_metadata_open(struct block_device *bdev,
0045                            sector_t data_block_size,
0046                            bool format_device);
0047 
0048 int dm_pool_metadata_close(struct dm_pool_metadata *pmd);
0049 
0050 /*
0051  * Compat feature flags.  Any incompat flags beyond the ones
0052  * specified below will prevent use of the thin metadata.
0053  */
0054 #define THIN_FEATURE_COMPAT_SUPP      0UL
0055 #define THIN_FEATURE_COMPAT_RO_SUPP   0UL
0056 #define THIN_FEATURE_INCOMPAT_SUPP    0UL
0057 
0058 /*
0059  * Device creation/deletion.
0060  */
0061 int dm_pool_create_thin(struct dm_pool_metadata *pmd, dm_thin_id dev);
0062 
0063 /*
0064  * An internal snapshot.
0065  *
0066  * You can only snapshot a quiesced origin i.e. one that is either
0067  * suspended or not instanced at all.
0068  */
0069 int dm_pool_create_snap(struct dm_pool_metadata *pmd, dm_thin_id dev,
0070             dm_thin_id origin);
0071 
0072 /*
0073  * Deletes a virtual device from the metadata.  It _is_ safe to call this
0074  * when that device is open.  Operations on that device will just start
0075  * failing.  You still need to call close() on the device.
0076  */
0077 int dm_pool_delete_thin_device(struct dm_pool_metadata *pmd,
0078                    dm_thin_id dev);
0079 
0080 /*
0081  * Commits _all_ metadata changes: device creation, deletion, mapping
0082  * updates.
0083  */
0084 int dm_pool_commit_metadata(struct dm_pool_metadata *pmd);
0085 
0086 /*
0087  * Discards all uncommitted changes.  Rereads the superblock, rolling back
0088  * to the last good transaction.  Thin devices remain open.
0089  * dm_thin_aborted_changes() tells you if they had uncommitted changes.
0090  *
0091  * If this call fails it's only useful to call dm_pool_metadata_close().
0092  * All other methods will fail with -EINVAL.
0093  */
0094 int dm_pool_abort_metadata(struct dm_pool_metadata *pmd);
0095 
0096 /*
0097  * Set/get userspace transaction id.
0098  */
0099 int dm_pool_set_metadata_transaction_id(struct dm_pool_metadata *pmd,
0100                     uint64_t current_id,
0101                     uint64_t new_id);
0102 
0103 int dm_pool_get_metadata_transaction_id(struct dm_pool_metadata *pmd,
0104                     uint64_t *result);
0105 
0106 /*
0107  * Hold/get root for userspace transaction.
0108  *
0109  * The metadata snapshot is a copy of the current superblock (minus the
0110  * space maps).  Userland can access the data structures for READ
0111  * operations only.  A small performance hit is incurred by providing this
0112  * copy of the metadata to userland due to extra copy-on-write operations
0113  * on the metadata nodes.  Release this as soon as you finish with it.
0114  */
0115 int dm_pool_reserve_metadata_snap(struct dm_pool_metadata *pmd);
0116 int dm_pool_release_metadata_snap(struct dm_pool_metadata *pmd);
0117 
0118 int dm_pool_get_metadata_snap(struct dm_pool_metadata *pmd,
0119                   dm_block_t *result);
0120 
0121 /*
0122  * Actions on a single virtual device.
0123  */
0124 
0125 /*
0126  * Opening the same device more than once will fail with -EBUSY.
0127  */
0128 int dm_pool_open_thin_device(struct dm_pool_metadata *pmd, dm_thin_id dev,
0129                  struct dm_thin_device **td);
0130 
0131 int dm_pool_close_thin_device(struct dm_thin_device *td);
0132 
0133 dm_thin_id dm_thin_dev_id(struct dm_thin_device *td);
0134 
0135 struct dm_thin_lookup_result {
0136     dm_block_t block;
0137     bool shared:1;
0138 };
0139 
0140 /*
0141  * Returns:
0142  *   -EWOULDBLOCK iff @can_issue_io is set and would issue IO
0143  *   -ENODATA iff that mapping is not present.
0144  *   0 success
0145  */
0146 int dm_thin_find_block(struct dm_thin_device *td, dm_block_t block,
0147                int can_issue_io, struct dm_thin_lookup_result *result);
0148 
0149 /*
0150  * Retrieve the next run of contiguously mapped blocks.  Useful for working
0151  * out where to break up IO.  Returns 0 on success, < 0 on error.
0152  */
0153 int dm_thin_find_mapped_range(struct dm_thin_device *td,
0154                   dm_block_t begin, dm_block_t end,
0155                   dm_block_t *thin_begin, dm_block_t *thin_end,
0156                   dm_block_t *pool_begin, bool *maybe_shared);
0157 
0158 /*
0159  * Obtain an unused block.
0160  */
0161 int dm_pool_alloc_data_block(struct dm_pool_metadata *pmd, dm_block_t *result);
0162 
0163 /*
0164  * Insert or remove block.
0165  */
0166 int dm_thin_insert_block(struct dm_thin_device *td, dm_block_t block,
0167              dm_block_t data_block);
0168 
0169 int dm_thin_remove_range(struct dm_thin_device *td,
0170              dm_block_t begin, dm_block_t end);
0171 
0172 /*
0173  * Queries.
0174  */
0175 bool dm_thin_changed_this_transaction(struct dm_thin_device *td);
0176 
0177 bool dm_pool_changed_this_transaction(struct dm_pool_metadata *pmd);
0178 
0179 bool dm_thin_aborted_changes(struct dm_thin_device *td);
0180 
0181 int dm_thin_get_highest_mapped_block(struct dm_thin_device *td,
0182                      dm_block_t *highest_mapped);
0183 
0184 int dm_thin_get_mapped_count(struct dm_thin_device *td, dm_block_t *result);
0185 
0186 int dm_pool_get_free_block_count(struct dm_pool_metadata *pmd,
0187                  dm_block_t *result);
0188 
0189 int dm_pool_get_free_metadata_block_count(struct dm_pool_metadata *pmd,
0190                       dm_block_t *result);
0191 
0192 int dm_pool_get_metadata_dev_size(struct dm_pool_metadata *pmd,
0193                   dm_block_t *result);
0194 
0195 int dm_pool_get_data_dev_size(struct dm_pool_metadata *pmd, dm_block_t *result);
0196 
0197 int dm_pool_block_is_shared(struct dm_pool_metadata *pmd, dm_block_t b, bool *result);
0198 
0199 int dm_pool_inc_data_range(struct dm_pool_metadata *pmd, dm_block_t b, dm_block_t e);
0200 int dm_pool_dec_data_range(struct dm_pool_metadata *pmd, dm_block_t b, dm_block_t e);
0201 
0202 /*
0203  * Returns -ENOSPC if the new size is too small and already allocated
0204  * blocks would be lost.
0205  */
0206 int dm_pool_resize_data_dev(struct dm_pool_metadata *pmd, dm_block_t new_size);
0207 int dm_pool_resize_metadata_dev(struct dm_pool_metadata *pmd, dm_block_t new_size);
0208 
0209 /*
0210  * Flicks the underlying block manager into read only mode, so you know
0211  * that nothing is changing.
0212  */
0213 void dm_pool_metadata_read_only(struct dm_pool_metadata *pmd);
0214 void dm_pool_metadata_read_write(struct dm_pool_metadata *pmd);
0215 
0216 int dm_pool_register_metadata_threshold(struct dm_pool_metadata *pmd,
0217                     dm_block_t threshold,
0218                     dm_sm_threshold_fn fn,
0219                     void *context);
0220 
0221 /*
0222  * Updates the superblock immediately.
0223  */
0224 int dm_pool_metadata_set_needs_check(struct dm_pool_metadata *pmd);
0225 bool dm_pool_metadata_needs_check(struct dm_pool_metadata *pmd);
0226 
0227 /*
0228  * Issue any prefetches that may be useful.
0229  */
0230 void dm_pool_issue_prefetches(struct dm_pool_metadata *pmd);
0231 
0232 /* Pre-commit callback */
0233 typedef int (*dm_pool_pre_commit_fn)(void *context);
0234 
0235 void dm_pool_register_pre_commit_callback(struct dm_pool_metadata *pmd,
0236                       dm_pool_pre_commit_fn fn,
0237                       void *context);
0238 
0239 /*----------------------------------------------------------------*/
0240 
0241 #endif