On May 05, 2023 / 11:28, Ziyang Zhang wrote: [...] > + > + if (S_ISBLK(st.st_mode)) { > + if (ioctl(fd, BLKGETSIZE64, &bytes) != 0) > + return -EBADF; > + if (ioctl(fd, BLKSSZGET, &bs) != 0) > + return -1; > + if (ioctl(fd, BLKPBSZGET, &pbs) != 0) > + return -1; Nit: the line above has some trailing tabs. > + } else if (S_ISREG(st.st_mode)) { > + bytes = st.st_size; > + } else { > + bytes = 0; > + } > + > + if (fcntl(fd, F_SETFL, O_DIRECT)) { > + /* buffered I/O */ > + ublk_log("%s: %s, ublk-loop fallback to buffered IO\n", > + __func__, strerror(errno)); > + } > + else { > + /* direct I/O */ > + if (p.basic.logical_bs_shift != ilog2(bs)) { > + ublk_err("%s: logical block size should be %d, I got %d\n", > + __func__, 1 << p.basic.logical_bs_shift, bs); > + return -1; > + } > + if (p.basic.physical_bs_shift != ilog2(pbs)) { > + ublk_err("%s: physical block size should be %d, I got %d\n", > + __func__, 1 << p.basic.physical_bs_shift, pbs); > + return -1; > + } > + } > + The line above also. > + if (p.basic.dev_sectors << 9 != bytes) { > + ublk_err("%s: device size should be %lld, I got %lld\n", > + __func__, p.basic.dev_sectors << 9, bytes); > + return -1; > + } > + > + dev->tgt.dev_size = bytes; > + dev->fds[1] = fd; > + dev->nr_fds += 1; > + > + return 0; > +} > + > const struct ublk_tgt_ops tgt_ops_list[] = { > { > .name = "null", > .init_tgt = ublk_null_tgt_init, > .queue_io = ublk_null_queue_io, > + .recover_tgt = ublk_null_tgt_recover, > }, > > { > @@ -1326,6 +1562,7 @@ const struct ublk_tgt_ops tgt_ops_list[] = { > .deinit_tgt = ublk_loop_tgt_deinit, > .queue_io = ublk_loop_queue_io, > .tgt_io_done = ublk_loop_io_done, > + .recover_tgt = ublk_loop_tgt_recover, > }, > }; > > @@ -1359,6 +1596,8 @@ int main(int argc, char *argv[]) > ret = cmd_dev_list(argc, argv); > else if (!strcmp(cmd, "help")) > ret = cmd_dev_help(argc, argv); > + else if (!strcmp(cmd, "recover")) > + ret = cmd_dev_recover(argc, argv); > out: > if (ret) > cmd_dev_help(argc, argv); > -- > 2.31.1 >