OPTION(filestore_fake_collections, 0, OPT_BOOL, false),
OPTION(filestore_dev, 0, OPT_STR, 0),
OPTION(filestore_btrfs_trans, 0, OPT_BOOL, true),
+ OPTION(filestore_btrfs_snap, 0, OPT_BOOL, false),
OPTION(filestore_flusher, 0, OPT_BOOL, true),
OPTION(filestore_flusher_max_fds, 0, OPT_INT, 512),
OPTION(filestore_sync_flush, 0, OPT_BOOL, false),
#define ATTR_MAX 80
-#define COMMIT_SNAP_ITEM "%lld"
+#define COMMIT_SNAP_ITEM "snap_%lld"
#ifndef __CYGWIN__
# ifndef DARWIN
volargs.fd = 0;
strcpy(volargs.name, "current");
int r = ::ioctl(fd, BTRFS_IOC_SUBVOL_CREATE, (unsigned long int)&volargs);
- char current_fn[PATH_MAX];
- snprintf(current_fn, sizeof(current_fn), "%s/current", basedir.c_str());
if (r == 0) {
// yay
dout(2) << " created btrfs subvol " << current_fn << dendl;
Transaction empty;
btrfs = 1;
- btrfs_snap = false;
- if (btrfs_snap) {
- snapdir_fd = ::open(basedir.c_str(), O_RDONLY);
+ // open some dir handles
+ basedir_fd = ::open(basedir.c_str(), O_RDONLY);
+ current_fd = ::open(current_fn, O_RDONLY);
+ dout(10) << "basedir_fd " << basedir_fd << "=" << basedir
+ << ", current_fd " << current_fd << "=" << current_fn << dendl;
+ if (true) { //g_conf.filestore_btrfs_snap) {
// get snap list
DIR *dir = ::opendir(basedir.c_str());
if (!dir)
::close(fsid_fd);
::close(op_fd);
+ ::close(current_fd);
+ ::close(basedir_fd);
if (g_conf.filestore_dev) {
char cmd[PATH_MAX];
dout(15) << "sync_entry committing " << cp << " sync_epoch " << sync_epoch << dendl;
+ bool do_snap = g_conf.filestore_btrfs_snap;
- if (btrfs_snap) {
+ if (do_snap) {
btrfs_ioctl_vol_args snapargs;
- snapargs.fd = snapdir_fd;
+ snapargs.fd = current_fd;
snprintf(snapargs.name, sizeof(snapargs.name), COMMIT_SNAP_ITEM, (long long unsigned)cp);
- dout(0) << "taking snap '" << snapargs.name << "'" << dendl;
- int r = ::ioctl(snapargs.fd, BTRFS_IOC_SNAP_CREATE, &snapargs);
+ dout(10) << "taking snap '" << snapargs.name << "'" << dendl;
+ int r = ::ioctl(basedir_fd, BTRFS_IOC_SNAP_CREATE, &snapargs);
char buf[100];
- dout(0) << "snap create '" << snapargs.name << "' got " << r
+ dout(20) << "snap create '" << snapargs.name << "' got " << r
<< " " << strerror_r(r < 0 ? errno : 0, buf, sizeof(buf)) << dendl;
+ assert(r == 0);
snaps.push_back(cp);
}
commit_started();
- if (!btrfs_snap) {
+ if (!do_snap) {
if (btrfs) {
dout(15) << "sync_entry doing btrfs sync" << dendl;
// do a full btrfs commit
commit_finish();
// remove old snaps?
- if (false && btrfs_snap) {
+ if (do_snap) {
while (snaps.size() > 2) {
btrfs_ioctl_vol_args snapargs;
- snapargs.fd = snapdir_fd;
+ snapargs.fd = 0;
snprintf(snapargs.name, sizeof(snapargs.name), COMMIT_SNAP_ITEM, (long long unsigned)snaps.front());
snaps.pop_front();
- dout(0) << "removing snap '" << snapargs.name << "'" << dendl;
- int r = ::ioctl(snapargs.fd, BTRFS_IOC_SNAP_DESTROY, &snapargs);
+ dout(10) << "removing snap '" << snapargs.name << "'" << dendl;
+ int r = ::ioctl(basedir_fd, BTRFS_IOC_SNAP_DESTROY, &snapargs);
char buf[100];
- dout(0) << "snap destroyed '" << snapargs.name << "' got " << r
+ dout(20) << "snap destroyed '" << snapargs.name << "' got " << r
<< " " << strerror_r(r < 0 ? errno : 0, buf, sizeof(buf)) << dendl;
+ assert(r == 0);
}
}
class FileStore : public JournalingObjectStore {
string basedir, journalpath;
+ char current_fn[PATH_MAX];
__u64 fsid;
int btrfs;
- bool btrfs_snap;
bool btrfs_trans_start_end;
int fsid_fd, op_fd;
- int snapdir_fd;
+ int basedir_fd, current_fd;
deque<__u64> snaps;
// fake attrs?
public:
FileStore(const char *base, const char *jdev = 0) :
basedir(base), journalpath(jdev ? jdev:""),
- btrfs(false), btrfs_snap(false), btrfs_trans_start_end(false),
+ btrfs(false), btrfs_trans_start_end(false),
fsid_fd(-1), op_fd(-1),
attrs(this), fake_attrs(false),
collections(this), fake_collections(false),
lock("FileStore::lock"),
sync_epoch(0), stop(false), sync_thread(this),
op_lock("FileStore::op_lock"), op_queue_len(0), op_queue_bytes(0), op_thread(this),
- flusher_queue_len(0), flusher_thread(this) { }
+ flusher_queue_len(0), flusher_thread(this) {
+ // init current_fn
+ snprintf(current_fn, sizeof(current_fn), "%s/current", basedir.c_str());
+ }
int mount();
int umount();