default:
out << "unknown";
}
- if (o.flags & BTRFS_IOC_UT_OP_FLAG_FD_SAVE) out << " FD_SAVE(" << o.fd_num << ")";
- if (o.flags & BTRFS_IOC_UT_OP_FLAG_FD_ARG0) out << " FD_ARG0";
- if (o.flags & BTRFS_IOC_UT_OP_FLAG_FD_ARG1) out << " FD_ARG1";
- if (o.flags & BTRFS_IOC_UT_OP_FLAG_FD_ARG2) out << " FD_ARG2";
- if (o.flags & BTRFS_IOC_UT_OP_FLAG_FD_ARG3) out << " FD_ARG3";
- if (o.flags & BTRFS_IOC_UT_OP_FLAG_FD_ARG4) out << " FD_ARG4";
return out;
}
op.args[0] = (unsigned long)fn;
op.args[1] = O_WRONLY | O_CREAT;
op.args[2] = 0644;
- op.flags = BTRFS_IOC_UT_OP_FLAG_FD_SAVE;
- op.fd_num = 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.flags = BTRFS_IOC_UT_OP_FLAG_FD_ARG0;
+ op.rval = 0;
+ op.flags = BTRFS_IOC_UT_OP_FLAG_FAIL_ON_NE;
ops.push_back(op);
}
break;
op.args[0] = (__s64)fn;
op.args[1] = O_WRONLY|O_CREAT;
op.args[2] = 0644;
- op.flags = BTRFS_IOC_UT_OP_FLAG_FD_SAVE;
- op.fd_num = 0;
+ 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());
op.args[1] = (__s64)(*it).c_str();
op.args[2] = (__s64)(*it).length();
op.args[3] = off;
- op.flags = BTRFS_IOC_UT_OP_FLAG_FD_ARG0;
+ 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.flags = BTRFS_IOC_UT_OP_FLAG_FD_ARG0;
+ op.rval = 0;
+ op.flags = BTRFS_IOC_UT_OP_FLAG_FAIL_ON_NE;
ops.push_back(op);
}
break;
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;
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;
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;
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);
}
}
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;
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);
}
}
op.op = BTRFS_IOC_UT_OP_OPEN;
op.args[0] = (__u64)fn;
op.args[1] = O_RDONLY;
- op.fd_num = 0;
+ 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.args[0] = (__u64)fn2;
op.args[1] = O_WRONLY|O_CREAT|O_TRUNC;
op.args[2] = 0644;
- op.fd_num = 1;
+ 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.args[1] = 0;
op.args[2] = 0;
op.args[3] = 0;
- op.flags = BTRFS_IOC_UT_OP_FLAG_FD_ARG0 | BTRFS_IOC_UT_OP_FLAG_FD_ARG1;
+ 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.flags = BTRFS_IOC_UT_OP_FLAG_FD_ARG0;
+ op.rval = 0;
+ op.flags = BTRFS_IOC_UT_OP_FLAG_FAIL_ON_LT;
ops.push_back(op);
op.args[0] = 1;
- op.flags = BTRFS_IOC_UT_OP_FLAG_FD_ARG0;
ops.push_back(op);
}
break;
op.op = BTRFS_IOC_UT_OP_OPEN;
op.args[0] = (__u64)fn;
op.args[1] = O_RDONLY;
- op.fd_num = 0;
+ 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.args[0] = (__u64)fn2;
op.args[1] = O_WRONLY|O_CREAT|O_TRUNC;
op.args[2] = 0644;
- op.fd_num = 1;
+ 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.args[1] = 0;
op.args[2] = t->get_length(); // offset
op.args[3] = t->get_length(); // length
- op.flags = BTRFS_IOC_UT_OP_FLAG_FD_ARG0 | BTRFS_IOC_UT_OP_FLAG_FD_ARG1;
+ 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.flags = BTRFS_IOC_UT_OP_FLAG_FD_ARG0;
+ op.rval = 0;
+ op.flags = BTRFS_IOC_UT_OP_FLAG_FAIL_ON_LT;
ops.push_back(op);
op.args[0] = 1;
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;
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;
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;
ut.ops_ptr = (__u64)&ops[0];
ut.num_fds = 2;
ut.metadata_ops = ops.size();
- ut.flags = 0;
+ ut.flags = BTRFS_IOC_UT_FLAG_WEDGEONFAIL;
- dout(20) << "USERTRANS ioctl on " << ops.size() << " ops" << dendl;
+ 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);
- dout(10) << "USERTRANS ioctl on " << ops.size() << " r = " << r
- << ", completed " << ut.ops_completed << " ops" << dendl;
+ 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) {
- for (unsigned i=0; i<ut.ops_completed; i++)
- dout(10) << "USERTRANS ioctl op[" << i << "] " << ops[i] << " = " << ops[i].rval << dendl;
+ dout(10) << "USERTRANS ioctl (" << ops.size() << " ops) r = " << r
+ << ", completed " << ut.ops_completed << " ops" << dendl;
assert(ut.ops_completed == ops.size());
r = 0;
+ } else {
+ 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)
struct btrfs_ioctl_vol_args)
/* usertrans ops */
-#define BTRFS_IOC_UT_OP_OPEN 1
-#define BTRFS_IOC_UT_OP_CLOSE 2
-#define BTRFS_IOC_UT_OP_PWRITE 3
-#define BTRFS_IOC_UT_OP_UNLINK 4
-#define BTRFS_IOC_UT_OP_LINK 5
-#define BTRFS_IOC_UT_OP_MKDIR 6
-#define BTRFS_IOC_UT_OP_RMDIR 7
-#define BTRFS_IOC_UT_OP_TRUNCATE 8
-#define BTRFS_IOC_UT_OP_SETXATTR 9
-#define BTRFS_IOC_UT_OP_REMOVEXATTR 10
-#define BTRFS_IOC_UT_OP_CLONERANGE 11
+/* the 'fd' values are _indices_ into a temporary fd table, see num_fds below */
+#define BTRFS_IOC_UT_OP_OPEN 1 /* path, flags, mode, fd */
+#define BTRFS_IOC_UT_OP_CLOSE 2 /* fd */
+#define BTRFS_IOC_UT_OP_PWRITE 3 /* fd, data, length, offset */
+#define BTRFS_IOC_UT_OP_UNLINK 4 /* path */
+#define BTRFS_IOC_UT_OP_LINK 5 /* oldpath, newpath */
+#define BTRFS_IOC_UT_OP_MKDIR 6 /* path, mode */
+#define BTRFS_IOC_UT_OP_RMDIR 7 /* path */
+#define BTRFS_IOC_UT_OP_TRUNCATE 8 /* path, size */
+#define BTRFS_IOC_UT_OP_SETXATTR 9 /* path, name, data, len */
+#define BTRFS_IOC_UT_OP_REMOVEXATTR 10 /* path, name */
+#define BTRFS_IOC_UT_OP_CLONERANGE 11 /* dst fd, src fd, off, len, dst off */
-#define BTRFS_IOC_UT_OP_FLAG_FD_SAVE (1<< 1)
-#define BTRFS_IOC_UT_OP_FLAG_FD_ARG0 (1<< 2)
-#define BTRFS_IOC_UT_OP_FLAG_FD_ARG1 (1<< 3)
-#define BTRFS_IOC_UT_OP_FLAG_FD_ARG2 (1<< 4)
-#define BTRFS_IOC_UT_OP_FLAG_FD_ARG3 (1<< 5)
-#define BTRFS_IOC_UT_OP_FLAG_FD_ARG4 (1<< 6)
-#define BTRFS_IOC_UT_OP_FLAG_FAIL_ON_NE (1<< 7)
-#define BTRFS_IOC_UT_OP_FLAG_FAIL_ON_EQ (1<< 8)
-#define BTRFS_IOC_UT_OP_FLAG_FAIL_ON_LT (1<< 9)
-#define BTRFS_IOC_UT_OP_FLAG_FAIL_ON_GT (1<<10)
-#define BTRFS_IOC_UT_OP_FLAG_FAIL_ON_LTE (1<<11)
-#define BTRFS_IOC_UT_OP_FLAG_FAIL_ON_GTE (1<<12)
+#define BTRFS_IOC_UT_OP_FLAG_FAIL_ON_NE (1<< 1)
+#define BTRFS_IOC_UT_OP_FLAG_FAIL_ON_EQ (1<< 2)
+#define BTRFS_IOC_UT_OP_FLAG_FAIL_ON_LT (1<< 3)
+#define BTRFS_IOC_UT_OP_FLAG_FAIL_ON_GT (1<< 4)
+#define BTRFS_IOC_UT_OP_FLAG_FAIL_ON_LTE (1<< 5)
+#define BTRFS_IOC_UT_OP_FLAG_FAIL_ON_GTE (1<< 6)
struct btrfs_ioctl_usertrans_op {
__u64 op;
__s64 args[5];
__s64 rval;
__u64 flags;
- __u64 fd_num;
};
/*
struct btrfs_ioctl_usertrans {
__u64 num_ops; /* in: # ops */
__u64 ops_ptr; /* in: usertrans_op array */
- __u64 num_fds; /* in: max fds we use */
+ __u64 num_fds; /* in: size of fd table (max fd + 1) */
__u64 data_bytes, metadata_ops; /* in: for space reservation */
__u64 flags; /* in: flags */
__u64 ops_completed; /* out: # ops completed */