From: yaoning Date: Thu, 19 Jan 2017 02:43:53 +0000 (+0800) Subject: rbd: add sparse size support in rbd X-Git-Tag: v12.0.2~197^2~3 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=8a83a2d61134123bee82257c057c80307141b148;p=ceph-ci.git rbd: add sparse size support in rbd add --sparse_size in rbd command options add calc_sparse_extent in rbd utils Signed-off-by: yaoning --- diff --git a/src/test/cli/rbd/help.t b/src/test/cli/rbd/help.t index 0f5ed40a290..e9b716ad736 100644 --- a/src/test/cli/rbd/help.t +++ b/src/test/cli/rbd/help.t @@ -196,7 +196,8 @@ [--data-pool ] [--journal-splay-width ] [--journal-object-size ] - [--journal-pool ] [--no-progress] + [--journal-pool ] [--sparse-size ] + [--no-progress] Copy src image to dest. @@ -227,6 +228,7 @@ --journal-splay-width arg number of active journal objects --journal-object-size arg size of journal objects --journal-pool arg pool for journal objects + --sparse-size arg sparse size in B/K/M [default: 4K] --no-progress disable progress output Image Features: @@ -588,7 +590,8 @@ [--stripe-count ] [--data-pool ] [--journal-splay-width ] [--journal-object-size ] - [--journal-pool ] [--no-progress] + [--journal-pool ] + [--sparse-size ] [--no-progress] [--export-format ] [--pool ] [--image ] @@ -620,6 +623,7 @@ --journal-splay-width arg number of active journal objects --journal-object-size arg size of journal objects --journal-pool arg pool for journal objects + --sparse-size arg sparse size in B/K/M [default: 4K] --no-progress disable progress output --export-format arg format of image file -p [ --pool ] arg pool name (deprecated) @@ -632,7 +636,7 @@ rbd help import-diff usage: rbd import-diff [--path ] [--pool ] [--image ] - [--no-progress] + [--sparse-size ] [--no-progress] Import an incremental diff. @@ -646,6 +650,7 @@ --path arg import file (or '-' for stdin) -p [ --pool ] arg pool name --image arg image name + --sparse-size arg sparse size in B/K/M [default: 4K] --no-progress disable progress output rbd help info diff --git a/src/tools/rbd/ArgumentTypes.cc b/src/tools/rbd/ArgumentTypes.cc index 9e11bdc77cf..b04fcc1da32 100644 --- a/src/tools/rbd/ArgumentTypes.cc +++ b/src/tools/rbd/ArgumentTypes.cc @@ -293,6 +293,12 @@ void add_size_option(boost::program_options::options_description *opt) { "image size (in M/G/T)"); } +void add_sparse_size_option(boost::program_options::options_description *opt) { + opt->add_options() + (IMAGE_SPARSE_SIZE.c_str(), po::value(), + "sparse size in B/K/M [default: 4K]"); +} + void add_path_options(boost::program_options::options_description *pos, boost::program_options::options_description *opt, const std::string &description) { diff --git a/src/tools/rbd/ArgumentTypes.h b/src/tools/rbd/ArgumentTypes.h index b8e555a0b77..d0ea09df900 100644 --- a/src/tools/rbd/ArgumentTypes.h +++ b/src/tools/rbd/ArgumentTypes.h @@ -70,6 +70,7 @@ static const std::string IMAGE_SIZE("size"); static const std::string IMAGE_STRIPE_UNIT("stripe-unit"); static const std::string IMAGE_STRIPE_COUNT("stripe-count"); static const std::string IMAGE_DATA_POOL("data-pool"); +static const std::string IMAGE_SPARSE_SIZE("sparse-size"); static const std::string JOURNAL_OBJECT_SIZE("journal-object-size"); static const std::string JOURNAL_SPLAY_WIDTH("journal-splay-width"); @@ -179,6 +180,8 @@ void add_create_journal_options( void add_size_option(boost::program_options::options_description *opt); +void add_sparse_size_option(boost::program_options::options_description *opt); + void add_path_options(boost::program_options::options_description *pos, boost::program_options::options_description *opt, const std::string &description); diff --git a/src/tools/rbd/Utils.cc b/src/tools/rbd/Utils.cc index 99ffc8053c4..53f6da33476 100644 --- a/src/tools/rbd/Utils.cc +++ b/src/tools/rbd/Utils.cc @@ -816,6 +816,36 @@ int snap_set(librbd::Image &image, const std::string &snap_name) { return 0; } +bool calc_sparse_extent(const bufferptr &bp, + size_t sparse_size, + uint64_t length, + size_t *write_offset, + size_t *write_length, + size_t *offset) { + size_t extent_size; + if (*offset + sparse_size > length) { + extent_size = length - *offset; + } else { + extent_size = sparse_size; + } + + bufferptr extent(bp, *offset, extent_size); + *offset += extent_size; + + bool extent_is_zero = extent.is_zero(); + if (!extent_is_zero) { + *write_length += extent_size; + } + if (extent_is_zero && *write_length == 0) { + *write_offset += extent_size; + } + + if ((extent_is_zero || *offset == length) && *write_length != 0) { + return true; + } + return false; +} + std::string image_id(librbd::Image& image) { std::string id; int r = image.get_id(&id); diff --git a/src/tools/rbd/Utils.h b/src/tools/rbd/Utils.h index a718ded0bde..0f72a40942c 100644 --- a/src/tools/rbd/Utils.h +++ b/src/tools/rbd/Utils.h @@ -33,6 +33,7 @@ void aio_completion_callback(librbd::completion_t completion, } // namespace detail static const std::string RBD_DIFF_BANNER ("rbd diff v1\n"); +static const size_t RBD_DEFAULT_SPARSE_SIZE = 4096; static const std::string RBD_IMAGE_BANNER_V2 ("rbd image v2\n"); static const std::string RBD_IMAGE_DIFFS_BANNER_V2 ("rbd image diffss v2\n"); @@ -167,6 +168,13 @@ int init_and_open_image(const std::string &pool_name, int snap_set(librbd::Image &image, const std::string &snap_name); +bool calc_sparse_extent(const bufferptr &bp, + size_t sparse_size, + uint64_t length, + size_t *write_offset, + size_t *write_length, + size_t *offset); + std::string image_id(librbd::Image& image); std::string mirror_image_state(librbd::mirror_image_state_t mirror_image_state);