Merge branch 'master' into v0.7-devel
Conflicts: persistent-data/file_utils.cc persistent-data/file_utils.h
This commit is contained in:
commit
3c02151a4f
1
CHANGES
1
CHANGES
@ -4,6 +4,7 @@ v0.6.2
|
|||||||
- Fix bug in thin_delta
|
- Fix bug in thin_delta
|
||||||
- Fix recent regression in thin_repair.
|
- Fix recent regression in thin_repair.
|
||||||
- Force g++-98 dialect
|
- Force g++-98 dialect
|
||||||
|
- Fix bug in thin_trim
|
||||||
|
|
||||||
v0.6.1
|
v0.6.1
|
||||||
======
|
======
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
using namespace base;
|
using namespace base;
|
||||||
|
using namespace bcache;
|
||||||
|
using namespace persistent_data;
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
|
|
||||||
@ -25,7 +27,7 @@ persistent_data::get_nr_blocks(string const &path, sector_t block_size)
|
|||||||
strerror(errno));
|
strerror(errno));
|
||||||
|
|
||||||
if (S_ISREG(info.st_mode) && info.st_size)
|
if (S_ISREG(info.st_mode) && info.st_size)
|
||||||
nr_blocks = div_up<block_address>(info.st_size, block_size);
|
nr_blocks = div_down<block_address>(info.st_size, block_size);
|
||||||
|
|
||||||
else if (S_ISBLK(info.st_mode)) {
|
else if (S_ISBLK(info.st_mode)) {
|
||||||
// To get the size of a block device we need to
|
// To get the size of a block device we need to
|
||||||
@ -48,10 +50,16 @@ persistent_data::get_nr_blocks(string const &path, sector_t block_size)
|
|||||||
return nr_blocks;
|
return nr_blocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
block_address
|
||||||
|
persistent_data::get_nr_metadata_blocks(string const &path)
|
||||||
|
{
|
||||||
|
return get_nr_blocks(path, MD_BLOCK_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
persistent_data::block_manager<>::ptr
|
persistent_data::block_manager<>::ptr
|
||||||
persistent_data::open_bm(std::string const &dev_path, block_manager<>::mode m, bool excl)
|
persistent_data::open_bm(std::string const &dev_path, block_manager<>::mode m, bool excl)
|
||||||
{
|
{
|
||||||
block_address nr_blocks = get_nr_blocks(dev_path);
|
block_address nr_blocks = get_nr_metadata_blocks(dev_path);
|
||||||
return block_manager<>::ptr(new block_manager<>(dev_path, nr_blocks, 1, m, excl));
|
return block_manager<>::ptr(new block_manager<>(dev_path, nr_blocks, 1, m, excl));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,6 +10,8 @@
|
|||||||
// FIXME: move to a different unit
|
// FIXME: move to a different unit
|
||||||
namespace persistent_data {
|
namespace persistent_data {
|
||||||
persistent_data::block_address get_nr_blocks(string const &path, sector_t block_size = MD_BLOCK_SIZE);
|
persistent_data::block_address get_nr_blocks(string const &path, sector_t block_size = MD_BLOCK_SIZE);
|
||||||
|
block_address get_nr_metadata_blocks(string const &path);
|
||||||
|
|
||||||
block_manager<>::ptr open_bm(std::string const &dev_path,
|
block_manager<>::ptr open_bm(std::string const &dev_path,
|
||||||
block_manager<>::mode m, bool excl = true);
|
block_manager<>::mode m, bool excl = true);
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ using namespace thin_provisioning;
|
|||||||
namespace {
|
namespace {
|
||||||
block_manager<>::ptr
|
block_manager<>::ptr
|
||||||
open_bm(string const &path) {
|
open_bm(string const &path) {
|
||||||
block_address nr_blocks = get_nr_blocks(path);
|
block_address nr_blocks = get_nr_metadata_blocks(path);
|
||||||
block_manager<>::mode m = block_manager<>::READ_ONLY;
|
block_manager<>::mode m = block_manager<>::READ_ONLY;
|
||||||
return block_manager<>::ptr(new block_manager<>(path, nr_blocks, 1, m));
|
return block_manager<>::ptr(new block_manager<>(path, nr_blocks, 1, m));
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ using namespace thin_provisioning;
|
|||||||
namespace {
|
namespace {
|
||||||
block_manager<>::ptr
|
block_manager<>::ptr
|
||||||
open_bm(string const &path) {
|
open_bm(string const &path) {
|
||||||
block_address nr_blocks = get_nr_blocks(path);
|
block_address nr_blocks = get_nr_metadata_blocks(path);
|
||||||
block_manager<>::mode m = block_manager<>::READ_ONLY;
|
block_manager<>::mode m = block_manager<>::READ_ONLY;
|
||||||
return block_manager<>::ptr(new block_manager<>(path, nr_blocks, 1, m));
|
return block_manager<>::ptr(new block_manager<>(path, nr_blocks, 1, m));
|
||||||
}
|
}
|
||||||
|
@ -22,17 +22,6 @@ using namespace thin_provisioning;
|
|||||||
//----------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
void confirm_pool_is_not_active() {
|
|
||||||
cout << "The pool must *not* be active when running this tool.\n"
|
|
||||||
<< "Do you wish to continue? [Y/N]\n"
|
|
||||||
<< endl;
|
|
||||||
|
|
||||||
string input;
|
|
||||||
cin >> input;
|
|
||||||
if (input != "Y")
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
class discard_emitter {
|
class discard_emitter {
|
||||||
public:
|
public:
|
||||||
discard_emitter(string const &data_dev, unsigned block_size, uint64_t nr_blocks)
|
discard_emitter(string const &data_dev, unsigned block_size, uint64_t nr_blocks)
|
||||||
@ -50,6 +39,8 @@ namespace {
|
|||||||
range[0] = block_to_byte(b);
|
range[0] = block_to_byte(b);
|
||||||
range[1] = block_to_byte(e) - range[0];
|
range[1] = block_to_byte(e) - range[0];
|
||||||
|
|
||||||
|
cerr << "emitting discard for blocks (" << b << ", " << e << "]\n";
|
||||||
|
|
||||||
if (ioctl(fd_, BLKDISCARD, &range))
|
if (ioctl(fd_, BLKDISCARD, &range))
|
||||||
throw runtime_error("discard ioctl failed");
|
throw runtime_error("discard ioctl failed");
|
||||||
}
|
}
|
||||||
@ -98,43 +89,57 @@ namespace {
|
|||||||
unsigned block_size_;
|
unsigned block_size_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class trim_visitor : public space_map_detail::visitor {
|
class trim_iterator : public space_map::iterator {
|
||||||
public:
|
public:
|
||||||
trim_visitor(discard_emitter &e)
|
trim_iterator(discard_emitter &e)
|
||||||
: emitter_(e) {
|
: emitter_(e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void visit(space_map_detail::missing_counts const &mc) {
|
virtual void operator() (block_address b, ref_t count) {
|
||||||
throw std::runtime_error("corrupt metadata, please use thin_check for details");
|
highest_ = b;
|
||||||
|
|
||||||
|
if (count) {
|
||||||
|
if (last_referenced_ && (b > *last_referenced_ + 1))
|
||||||
|
emitter_.emit(*last_referenced_ + 1, b);
|
||||||
|
|
||||||
|
last_referenced_ = b;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void visit(block_address b, uint32_t count) {
|
void complete() {
|
||||||
if (last_visited_ && (b > *last_visited_ + 1))
|
if (last_referenced_) {
|
||||||
emitter_.emit(*last_visited_ + 1, b);
|
if (*last_referenced_ != *highest_)
|
||||||
|
emitter_.emit(*last_referenced_, *highest_ + 1ull);
|
||||||
|
|
||||||
last_visited_ = b;
|
} else if (highest_)
|
||||||
|
emitter_.emit(0ull, *highest_ + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
discard_emitter &emitter_;
|
discard_emitter &emitter_;
|
||||||
boost::optional<block_address> last_visited_;
|
boost::optional<block_address> last_referenced_;
|
||||||
|
boost::optional<block_address> highest_;
|
||||||
};
|
};
|
||||||
|
|
||||||
int trim(string const &metadata_dev, string const &data_dev) {
|
int trim(string const &metadata_dev, string const &data_dev) {
|
||||||
|
cerr << "in trim\n";
|
||||||
|
|
||||||
// We can trim any block that has zero count in the data
|
// We can trim any block that has zero count in the data
|
||||||
// space map.
|
// space map.
|
||||||
block_manager<>::ptr bm = open_bm(metadata_dev, block_manager<>::READ_ONLY);
|
block_manager<>::ptr bm = open_bm(metadata_dev, block_manager<>::READ_ONLY);
|
||||||
metadata md(bm);
|
metadata md(bm);
|
||||||
|
|
||||||
if (!md.data_sm_->get_nr_free())
|
if (!md.data_sm_->get_nr_free()) {
|
||||||
|
cerr << "All data blocks allocated, nothing to discard\n";
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
discard_emitter de(data_dev, md.sb_.data_block_size_,
|
discard_emitter de(data_dev, md.sb_.data_block_size_,
|
||||||
md.data_sm_->get_nr_blocks());
|
md.data_sm_->get_nr_blocks());
|
||||||
trim_visitor tv(de);
|
trim_iterator ti(de);
|
||||||
|
|
||||||
confirm_pool_is_not_active();
|
md.data_sm_->iterate(ti);
|
||||||
md.data_sm_->visit(tv);
|
ti.complete();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -155,9 +160,8 @@ thin_trim_cmd::thin_trim_cmd()
|
|||||||
void
|
void
|
||||||
thin_trim_cmd::usage(std::ostream &out) const
|
thin_trim_cmd::usage(std::ostream &out) const
|
||||||
{
|
{
|
||||||
out << "Usage: " << get_name() << " [options] {device|file}\n"
|
out << "Usage: " << get_name() << " [options] --metadata-dev {device|file} --data-dev {device|file}\n"
|
||||||
<< "Options:\n"
|
<< "Options:\n"
|
||||||
<< " {--pool-inactive}\n"
|
|
||||||
<< " {-h|--help}\n"
|
<< " {-h|--help}\n"
|
||||||
<< " {-V|--version}" << endl;
|
<< " {-V|--version}" << endl;
|
||||||
}
|
}
|
||||||
@ -188,6 +192,10 @@ thin_trim_cmd::run(int argc, char **argv)
|
|||||||
fs.data_dev = optarg;
|
fs.data_dev = optarg;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
cerr << "--pool-inactive no longer required since we ensure the metadata device is opened exclusively.\n";
|
||||||
|
break;
|
||||||
|
|
||||||
case 'h':
|
case 'h':
|
||||||
usage(cout);
|
usage(cout);
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user