+static void binject_unmap_dev(struct thread_data *td, struct binject_file *bf)
+{
+ struct b_ioctl_cmd bic;
+ int fdb;
+
+ if (bf->fd >= 0) {
+ close(bf->fd);
+ bf->fd = -1;
+ }
+
+ fdb = open("/dev/binject-ctl", O_RDWR);
+ if (fdb < 0) {
+ td_verror(td, errno, "open binject-ctl");
+ return;
+ }
+
+ bic.minor = bf->minor;
+
+ if (ioctl(fdb, 1, &bic) < 0) {
+ td_verror(td, errno, "binject dev unmap");
+ close(fdb);
+ return;
+ }
+
+ close(fdb);
+}
+
+static int binject_map_dev(struct thread_data *td, struct binject_file *bf,
+ int fd)
+{
+ struct b_ioctl_cmd bic;
+ char name[80];
+ struct stat sb;
+ int fdb, dev_there, loops;
+
+ fdb = open("/dev/binject-ctl", O_RDWR);
+ if (fdb < 0) {
+ td_verror(td, errno, "binject ctl open");
+ return 1;
+ }
+
+ bic.fd = fd;
+
+ if (ioctl(fdb, 0, &bic) < 0) {
+ td_verror(td, errno, "binject dev map");
+ close(fdb);
+ return 1;
+ }
+
+ bf->minor = bic.minor;
+
+ sprintf(name, "/dev/binject%u", bf->minor);
+
+ /*
+ * Wait for udev to create the node...
+ */
+ dev_there = loops = 0;
+ do {
+ if (!stat(name, &sb)) {
+ dev_there = 1;
+ break;
+ }
+
+ usleep(10000);
+ } while (++loops < 100);
+
+ close(fdb);
+
+ if (!dev_there) {
+ log_err("fio: timed out waiting for binject dev\n");
+ goto err_unmap;
+ }
+
+ bf->fd = open(name, O_RDWR);
+ if (bf->fd < 0) {
+ td_verror(td, errno, "binject dev open");
+err_unmap:
+ binject_unmap_dev(td, bf);
+ return 1;
+ }
+
+ return 0;
+}
+
+static int fio_binject_close_file(struct thread_data *td, struct fio_file *f)
+{
+ struct binject_file *bf = (struct binject_file *) f->file_data;
+
+ if (bf) {
+ binject_unmap_dev(td, bf);
+ free(bf);
+ f->file_data = 0;
+ return generic_close_file(td, f);
+ }
+
+ return 0;
+}
+