diff --git a/tests/src/parallel_restore.c b/tests/src/parallel_restore.c index e45f7121..b6c82657 100644 --- a/tests/src/parallel_restore.c +++ b/tests/src/parallel_restore.c @@ -601,7 +601,7 @@ static int do_restore(struct opts *opts) ret = scoutfs_parallel_restore_create_writer(&wri); error_exit(ret, "create writer %d", ret); - ret = scoutfs_parallel_restore_import_super(wri, super); + ret = scoutfs_parallel_restore_import_super(wri, super, dev_fd); error_exit(ret, "import super %d", ret); slices = calloc(1 + opts->nr_writers, sizeof(struct scoutfs_parallel_restore_slice)); diff --git a/tests/src/restore_copy.c b/tests/src/restore_copy.c index 47f28796..7979443f 100644 --- a/tests/src/restore_copy.c +++ b/tests/src/restore_copy.c @@ -672,7 +672,7 @@ static int do_restore(struct opts *opts) ret = scoutfs_parallel_restore_create_writer(&wri); error_exit(ret, "create writer %d", ret); - ret = scoutfs_parallel_restore_import_super(wri, super); + ret = scoutfs_parallel_restore_import_super(wri, super, dev_fd); error_exit(ret, "import super %d", ret); slices = calloc(2, sizeof(struct scoutfs_parallel_restore_slice)); diff --git a/utils/src/parallel_restore.c b/utils/src/parallel_restore.c index 18e9797b..2c18dc9a 100644 --- a/utils/src/parallel_restore.c +++ b/utils/src/parallel_restore.c @@ -1816,13 +1816,58 @@ out: return count > 0 ? 0 : err; } +/* + * Here we take in a dev's fd an read its quorum blocks to see if the dev has + * been mounted before + */ +static spr_err_t scoutfs_check_if_previous_mount(int fd) +{ + struct scoutfs_quorum_block *blk = NULL; + struct scoutfs_quorum_block_event *ev; + u64 blkno; + int i, j; + spr_err_t err; + + for (i = 0; i < SCOUTFS_QUORUM_MAX_SLOTS; i++) { + blkno = SCOUTFS_QUORUM_BLKNO + i; + err = read_block(fd, blkno, SCOUTFS_BLOCK_SM_SHIFT, (void **)&blk); + if (!blk) + return EINVAL; + + dprintf("quorum block read; quorum bklno: %llu, err_val: %d\n", blkno, err); + if (err) { + free(blk); + return err; + } + + for (j = 0; j < SCOUTFS_QUORUM_EVENT_NR; j++) { + ev = &blk->events[j]; + if (ev->ts.sec || ev->ts.nsec) { + free(blk); + return EINVAL; + } + } + + free(blk); + } + + return err; +} + spr_err_t scoutfs_parallel_restore_import_super(struct scoutfs_parallel_restore_writer *wri, - struct scoutfs_super_block *super) + struct scoutfs_super_block *super, int fd) { spr_err_t err; u64 start; u64 len; + /* + * check the device we are restoring into to make sure + * that it has has never been mounted + */ + if (scoutfs_check_if_previous_mount(fd)) + return EINVAL; + if (le64_to_cpu(super->fmt_vers) < 2) return EINVAL; diff --git a/utils/src/parallel_restore.h b/utils/src/parallel_restore.h index 075c71ae..4f4c3558 100644 --- a/utils/src/parallel_restore.h +++ b/utils/src/parallel_restore.h @@ -97,7 +97,7 @@ spr_err_t scoutfs_parallel_restore_write_buf(struct scoutfs_parallel_restore_wri size_t *count_ret); spr_err_t scoutfs_parallel_restore_import_super(struct scoutfs_parallel_restore_writer *wri, - struct scoutfs_super_block *super); + struct scoutfs_super_block *super, int fd); spr_err_t scoutfs_parallel_restore_export_super(struct scoutfs_parallel_restore_writer *wri, struct scoutfs_super_block *super);