# ifndef DARWIN
# include "btrfs_ioctl.h"
-ostream& operator<<(ostream& out, btrfs_ioctl_usertrans_op& o)
-{
- switch (o.op) {
- case BTRFS_IOC_UT_OP_OPEN:
- out << "open " << (const char *)o.args[0] << " " << oct << "0" << o.args[1] << dec;
- break;
- case BTRFS_IOC_UT_OP_CLOSE:
- out << "close " << o.args[0];
- break;
- case BTRFS_IOC_UT_OP_PWRITE:
- out << "pwrite " << o.args[0] << " " << (void *)o.args[1] << " " << o.args[2] << "~" << o.args[3];
- break;
- case BTRFS_IOC_UT_OP_UNLINK:
- out << "unlink " << (const char *)o.args[0];
- break;
- case BTRFS_IOC_UT_OP_LINK:
- out << "link " << (const char *)o.args[0] << " " << (const char *)o.args[1];
- break;
- case BTRFS_IOC_UT_OP_MKDIR:
- out << "mkdir " << (const char *)o.args[0];
- break;
- case BTRFS_IOC_UT_OP_RMDIR:
- out << "rmdir " << (const char *)o.args[0];
- break;
- case BTRFS_IOC_UT_OP_TRUNCATE:
- out << "truncate " << (const char*)o.args[0] << " " << o.args[1];
- break;
- case BTRFS_IOC_UT_OP_SETXATTR:
- out << "setxattr " << (const char*)o.args[0] << " " << (const char *)o.args[1] << " "
- << (void *)o.args[2] << " " << o.args[3];
- break;
- case BTRFS_IOC_UT_OP_REMOVEXATTR:
- out << "removexattr " << (const char*)o.args[0] << " " << (const char *)o.args[1];
- break;
- case BTRFS_IOC_UT_OP_CLONERANGE:
- out << "clonerange " << o.args[0] << " " << o.args[1] << " " << o.args[2] << "~" << o.args[3];
- break;
- default:
- out << "unknown";
- }
- return out;
-}
# endif
dout(0) << " found snaps " << snaps << dendl;
}
- //btrfs_usertrans = false;
btrfs_trans_start_end = true; // trans start/end interface
- r = -1; //apply_transaction(empty, 0);
+ r = apply_transaction(empty, 0);
if (r == 0) {
- dout(0) << "mount btrfs USERTRANS ioctl is supported" << dendl;
+ dout(0) << "mount btrfs TRANS_START ioctl is supported" << dendl;
} else {
- //dout(0) << "mount btrfs USERTRANS ioctl is NOT supported: " << strerror_r(-r, buf, sizeof(buf)) << dendl;
- btrfs_usertrans = false;
- r = apply_transaction(empty, 0);
- if (r == 0) {
- dout(0) << "mount btrfs TRANS_START ioctl is supported" << dendl;
- } else {
- dout(0) << "mount btrfs TRANS_START ioctl is NOT supported: " << strerror_r(-r, buf, sizeof(buf)) << dendl;
- }
+ dout(0) << "mount btrfs TRANS_START ioctl is NOT supported: " << strerror_r(-r, buf, sizeof(buf)) << dendl;
}
if (r == 0) {
// do we have the shiny new CLONE_RANGE ioctl?
ops += (*p)->get_num_ops();
}
- if (btrfs_usertrans) {
- r = _do_usertrans(tls);
- } else {
- int id = _transaction_start(bytes, ops);
- if (id < 0) {
- op_journal_start();
- op_finish();
- return id;
- }
-
- for (list<Transaction*>::iterator p = tls.begin();
- p != tls.end();
- p++) {
- r = _do_transaction(**p);
- if (r < 0)
- break;
- }
+ int id = _transaction_start(bytes, ops);
+ if (id < 0) {
+ op_journal_start();
+ op_finish();
+ return id;
+ }
- _transaction_finish(id);
+ for (list<Transaction*>::iterator p = tls.begin();
+ p != tls.end();
+ p++) {
+ r = _do_transaction(**p);
+ if (r < 0)
+ break;
}
+
+ _transaction_finish(id);
op_journal_start();
dout(10) << "op_seq is " << op_seq << dendl;
/*********************************************/
-int FileStore::_do_usertrans(list<Transaction*>& ls)
-{
- btrfs_ioctl_usertrans ut;
- vector<btrfs_ioctl_usertrans_op> ops;
- list<char*> str;
- bool start_sync = false;
- btrfs_ioctl_usertrans_op op;
-
- memset(&ut, 0, sizeof(ut));
-
- for (list<Transaction*>::iterator p = ls.begin(); p != ls.end(); p++) {
- Transaction *t = *p;
-
- while (t->have_op()) {
- int opcode = t->get_op();
-
- memset(&op, 0, sizeof(op));
-
- switch (opcode) {
- case Transaction::OP_TOUCH:
- {
- char *fn = new char[PATH_MAX];
- str.push_back(fn);
- get_coname(t->get_cid(), t->get_oid(), fn);
-
- memset(&op, 0, sizeof(op));
- op.op = BTRFS_IOC_UT_OP_OPEN;
- op.args[0] = (unsigned long)fn;
- op.args[1] = O_WRONLY | O_CREAT;
- op.args[2] = 0644;
- op.args[3] = 0;
- op.rval = 0;
- op.flags = BTRFS_IOC_UT_OP_FLAG_FAIL_ON_LT;
- ops.push_back(op);
-
- memset(&op, 0, sizeof(op));
- op.op = BTRFS_IOC_UT_OP_CLOSE;
- op.args[0] = 0;
- op.rval = 0;
- op.flags = BTRFS_IOC_UT_OP_FLAG_FAIL_ON_NE;
- ops.push_back(op);
- }
- break;
-
- case Transaction::OP_WRITE:
- case Transaction::OP_ZERO: // write actual zeros.
- {
- __u64 off = t->get_length();
- __u64 len = t->get_length();
- bufferlist bl;
- if (opcode == Transaction::OP_WRITE)
- bl = t->get_bl();
- else {
- bufferptr bp(len);
- bp.zero();
- bl.push_back(bp);
- }
- char *fn = new char[PATH_MAX];
- str.push_back(fn);
- get_coname(t->get_cid(), t->get_oid(), fn);
-
- memset(&op, 0, sizeof(op));
- op.op = BTRFS_IOC_UT_OP_OPEN;
- op.args[0] = (__s64)fn;
- op.args[1] = O_WRONLY|O_CREAT;
- op.args[2] = 0644;
- op.args[3] = 0;
- op.rval = 0;
- op.flags = BTRFS_IOC_UT_OP_FLAG_FAIL_ON_LT;
- ops.push_back(op);
-
- assert(len == bl.length());
- for (list<bufferptr>::const_iterator it = bl.buffers().begin();
- it != bl.buffers().end();
- it++) {
- memset(&op, 0, sizeof(op));
- op.op = BTRFS_IOC_UT_OP_PWRITE;
- op.args[0] = 0;
- op.args[1] = (__s64)(*it).c_str();
- op.args[2] = (__s64)(*it).length();
- op.args[3] = off;
- op.rval = op.args[2];
- op.flags = BTRFS_IOC_UT_OP_FLAG_FAIL_ON_NE;
- ops.push_back(op);
- off += op.args[2];
- }
-
- memset(&op, 0, sizeof(op));
- op.op = BTRFS_IOC_UT_OP_CLOSE;
- op.args[0] = 0;
- op.rval = 0;
- op.flags = BTRFS_IOC_UT_OP_FLAG_FAIL_ON_NE;
- ops.push_back(op);
- }
- break;
-
- case Transaction::OP_TRUNCATE:
- {
- char *fn = new char[PATH_MAX];
- str.push_back(fn);
- get_coname(t->get_cid(), t->get_oid(), fn);
-
- memset(&op, 0, sizeof(op));
- op.op = BTRFS_IOC_UT_OP_TRUNCATE;
- op.args[0] = (__s64)fn;
- op.args[1] = t->get_length();
- op.rval = 0;
- op.flags = BTRFS_IOC_UT_OP_FLAG_FAIL_ON_NE;
- ops.push_back(op);
- }
- break;
-
- case Transaction::OP_COLL_REMOVE:
- case Transaction::OP_REMOVE:
- {
- char *fn = new char[PATH_MAX];
- str.push_back(fn);
- get_coname(t->get_cid(), t->get_oid(), fn);
-
- memset(&op, 0, sizeof(op));
- op.op = BTRFS_IOC_UT_OP_UNLINK;
- op.args[0] = (__u64)fn;
- op.rval = 0;
- //op.flags = BTRFS_IOC_UT_OP_FLAG_FAIL_ON_NE;
- ops.push_back(op);
- }
- break;
-
- case Transaction::OP_SETATTR:
- case Transaction::OP_COLL_SETATTR:
- {
- bufferlist bl = t->get_bl();
- char *fn = new char[PATH_MAX];
- str.push_back(fn);
-
- if (opcode == Transaction::OP_SETATTR)
- get_coname(t->get_cid(), t->get_oid(), fn);
- else
- get_cdir(t->get_cid(), fn);
-
- char *aname = new char[ATTR_MAX];
- str.push_back(aname);
- sprintf(aname, "user.ceph.%s", t->get_attrname());
-
- memset(&op, 0, sizeof(op));
- op.op = BTRFS_IOC_UT_OP_SETXATTR;
- op.args[0] = (__u64)fn;
- op.args[1] = (__u64)aname;
- op.args[2] = (__u64)bl.c_str();
- op.args[3] = bl.length();
- op.args[4] = 0;
- op.rval = 0;
- op.flags = BTRFS_IOC_UT_OP_FLAG_FAIL_ON_NE;
- ops.push_back(op);
- }
- break;
-
- case Transaction::OP_SETATTRS:
- case Transaction::OP_COLL_SETATTRS:
- {
- char *fn = new char[PATH_MAX];
- str.push_back(fn);
-
- if (opcode == Transaction::OP_SETATTRS)
- get_coname(t->get_cid(), t->get_oid(), fn);
- else
- get_cdir(t->get_cid(), fn);
-
- const map<nstring,bufferptr>& aset = t->get_attrset();
- for (map<nstring,bufferptr>::const_iterator p = aset.begin();
- p != aset.end();
- p++) {
- char *aname = new char[ATTR_MAX];
- str.push_back(aname);
- sprintf(aname, "user.ceph.%s", p->first.c_str());
-
- memset(&op, 0, sizeof(op));
- op.op = BTRFS_IOC_UT_OP_SETXATTR;
- op.args[0] = (__u64)fn;
- op.args[1] = (__u64)aname;
- op.args[2] = (__u64)p->second.c_str();
- op.args[3] = p->second.length();
- op.args[4] = 0;
- op.rval = 0;
- op.flags = BTRFS_IOC_UT_OP_FLAG_FAIL_ON_LT;
- ops.push_back(op);
- }
- }
- break;
-
- case Transaction::OP_RMATTR:
- case Transaction::OP_COLL_RMATTR:
- {
- char *fn = new char[PATH_MAX];
- str.push_back(fn);
- if (opcode == Transaction::OP_RMATTR)
- get_coname(t->get_cid(), t->get_oid(), fn);
- else
- get_cdir(t->get_cid(), fn);
-
- char *aname = new char[ATTR_MAX];
- str.push_back(aname);
- sprintf(aname, "user.ceph.%s", t->get_attrname());
-
- memset(&op, 0, sizeof(op));
- op.op = BTRFS_IOC_UT_OP_REMOVEXATTR;
- op.args[0] = (__u64)fn;
- op.args[1] = (__u64)aname;
- op.rval = 0;
- op.flags = BTRFS_IOC_UT_OP_FLAG_FAIL_ON_LT;
- ops.push_back(op);
- }
- break;
-
- case Transaction::OP_RMATTRS:
- {
- char *fn = new char[PATH_MAX];
- str.push_back(fn);
- get_coname(t->get_cid(), t->get_oid(), fn);
-
- map<nstring,bufferptr> aset;
- _getattrs(fn, aset);
-
- for (map<nstring,bufferptr>::iterator p = aset.begin(); p != aset.end(); p++) {
- char *aname = new char[ATTR_MAX];
- str.push_back(aname);
- sprintf(aname, "user.ceph.%s", p->first.c_str());
-
- memset(&op, 0, sizeof(op));
- op.op = BTRFS_IOC_UT_OP_REMOVEXATTR;
- op.args[0] = (__u64)fn;
- op.args[1] = (__u64)aname;
- op.rval = 0;
- op.flags = BTRFS_IOC_UT_OP_FLAG_FAIL_ON_LT;
- ops.push_back(op);
- }
- }
- break;
-
- case Transaction::OP_CLONE:
- {
- coll_t cid = t->get_cid();
-
- char *fn = new char[PATH_MAX];
- str.push_back(fn);
- get_coname(cid, t->get_oid(), fn);
-
- char *fn2 = new char[PATH_MAX];
- str.push_back(fn2);
- get_coname(cid, t->get_oid(), fn2);
-
- memset(&op, 0, sizeof(op));
- op.op = BTRFS_IOC_UT_OP_OPEN;
- op.args[0] = (__u64)fn;
- op.args[1] = O_RDONLY;
- op.args[2] = 0;
- op.rval = 0;
- op.flags = BTRFS_IOC_UT_OP_FLAG_FAIL_ON_LT;
- ops.push_back(op);
-
- memset(&op, 0, sizeof(op));
- op.op = BTRFS_IOC_UT_OP_OPEN;
- op.args[0] = (__u64)fn2;
- op.args[1] = O_WRONLY|O_CREAT|O_TRUNC;
- op.args[2] = 0644;
- op.args[3] = 1;
- op.rval = 0;
- op.flags = BTRFS_IOC_UT_OP_FLAG_FAIL_ON_LT;
- ops.push_back(op);
-
- memset(&op, 0, sizeof(op));
- op.op = BTRFS_IOC_UT_OP_CLONERANGE;
- op.args[0] = 1;
- op.args[1] = 0;
- op.args[2] = 0;
- op.args[3] = 0;
- op.rval = 0;
- op.flags = BTRFS_IOC_UT_OP_FLAG_FAIL_ON_LT;
- ops.push_back(op);
-
- memset(&op, 0, sizeof(op));
- op.op = BTRFS_IOC_UT_OP_CLOSE;
- op.args[0] = 0;
- op.rval = 0;
- op.flags = BTRFS_IOC_UT_OP_FLAG_FAIL_ON_LT;
- ops.push_back(op);
-
- op.args[0] = 1;
- ops.push_back(op);
- }
- break;
-
- case Transaction::OP_CLONERANGE:
- {
- coll_t cid = t->get_cid();
-
- char *fn = new char[PATH_MAX];
- str.push_back(fn);
- get_coname(cid, t->get_oid(), fn);
-
- char *fn2 = new char[PATH_MAX];
- str.push_back(fn2);
- get_coname(cid, t->get_oid(), fn2);
-
- memset(&op, 0, sizeof(op));
- op.op = BTRFS_IOC_UT_OP_OPEN;
- op.args[0] = (__u64)fn;
- op.args[1] = O_RDONLY;
- op.args[2] = 0;
- op.rval = 0;
- op.flags = BTRFS_IOC_UT_OP_FLAG_FAIL_ON_LT;
- ops.push_back(op);
-
- memset(&op, 0, sizeof(op));
- op.op = BTRFS_IOC_UT_OP_OPEN;
- op.args[0] = (__u64)fn2;
- op.args[1] = O_WRONLY|O_CREAT|O_TRUNC;
- op.args[2] = 0644;
- op.args[3] = 1;
- op.rval = 0;
- op.flags = BTRFS_IOC_UT_OP_FLAG_FAIL_ON_LT;
- ops.push_back(op);
-
- memset(&op, 0, sizeof(op));
- op.op = BTRFS_IOC_UT_OP_CLONERANGE;
- op.args[0] = 1;
- op.args[1] = 0;
- op.args[2] = t->get_length(); // offset
- op.args[3] = t->get_length(); // length
- op.rval = 0;
- op.flags = BTRFS_IOC_UT_OP_FLAG_FAIL_ON_LT;
- ops.push_back(op);
-
- memset(&op, 0, sizeof(op));
- op.op = BTRFS_IOC_UT_OP_CLOSE;
- op.args[0] = 0;
- op.rval = 0;
- op.flags = BTRFS_IOC_UT_OP_FLAG_FAIL_ON_LT;
- ops.push_back(op);
-
- op.args[0] = 1;
- ops.push_back(op);
- }
- break;
-
- case Transaction::OP_MKCOLL:
- {
- char *fn = new char[PATH_MAX];
- str.push_back(fn);
- get_cdir(t->get_cid(), fn);
-
- memset(&op, 0, sizeof(op));
- op.op = BTRFS_IOC_UT_OP_MKDIR;
- op.args[0] = (__u64)fn;
- op.args[1] = 0755;
- op.rval = 0;
- op.flags = BTRFS_IOC_UT_OP_FLAG_FAIL_ON_LT;
- ops.push_back(op);
- }
- break;
-
- case Transaction::OP_RMCOLL:
- {
- char *fn = new char[PATH_MAX];
- str.push_back(fn);
- get_cdir(t->get_cid(), fn);
-
- memset(&op, 0, sizeof(op));
- op.op = BTRFS_IOC_UT_OP_RMDIR;
- op.args[0] = (__u64)fn;
- op.rval = 0;
- op.flags = BTRFS_IOC_UT_OP_FLAG_FAIL_ON_LT;
- ops.push_back(op);
- }
- break;
-
- case Transaction::OP_COLL_ADD:
- {
- const sobject_t& oid = t->get_oid();
-
- char *fn = new char[PATH_MAX];
- str.push_back(fn);
- get_coname(t->get_cid(), oid, fn);
-
- char *nfn = new char[PATH_MAX];
- str.push_back(nfn);
- get_coname(t->get_cid(), oid, nfn);
-
- memset(&op, 0, sizeof(op));
- op.op = BTRFS_IOC_UT_OP_LINK;
- op.args[0] = (__u64)fn;
- op.args[1] = (__u64)nfn;
- op.rval = 0;
- op.flags = BTRFS_IOC_UT_OP_FLAG_FAIL_ON_LT;
- ops.push_back(op);
- }
- break;
-
- case Transaction::OP_STARTSYNC:
- {
- start_sync = true;
- }
- break;
-
- default:
- cerr << "bad op " << opcode << std::endl;
- assert(0);
- }
- }
-
- ut.data_bytes += t->get_num_bytes();
- }
-
- ut.num_ops = ops.size();
- ut.ops_ptr = (__u64)&ops[0];
- ut.num_fds = 2;
- ut.metadata_ops = ops.size();
- ut.flags = BTRFS_IOC_UT_FLAG_WEDGEONFAIL;
-
- dout(20) << "USERTRANS ioctl (" << ops.size() << " ops)" << dendl;
- for (unsigned i=0; i<ops.size(); i++)
- dout(20) << "USERTRANS ioctl op[" << i << "] " << ops[i] << " =? " << ops[i].rval << dendl;
-
- int r = ::ioctl(op_fd, BTRFS_IOC_USERTRANS, &ut);
- unsigned i;
- for (i=0; i<ut.ops_completed; i++)
- dout(10) << "USERTRANS ioctl op[" << i << "] " << ops[i] << " = " << ops[i].rval << dendl;
- if (r >= 0) {
- dout(10) << "USERTRANS ioctl (" << ops.size() << " ops) r = " << r
- << ", completed " << ut.ops_completed << " ops" << dendl;
- assert(ut.ops_completed == ops.size());
- r = 0;
- } else {
- if (i < ops.size())
- dout(10) << "USERTRANS ioctl op[" << i << "] " << ops[i] << " = " << ops[i].rval << dendl;
-
- char errbuf[100];
- dout(10) << "USERTRANS ioctl (" << ops.size() << " ops) r = " << r
- << " (" << strerror_r(errno, errbuf, sizeof(errbuf)) << ")"
- << ", completed " << ut.ops_completed << " ops" << dendl;
- r = --errno;
- }
-
- if (start_sync)
- _start_sync();
-
- while (!str.empty()) {
- delete str.front();
- str.pop_front();
- }
-
- return r;
-}
-
// --------------------