btrfs-progs: send: fix handling of -c option

When two or more -c options are specified, cannot find a suitable
parent. So, output stream is bigger than correct one.

[before]
At subvol Snap1
At subvol Snap2
At subvol ../SnapY
-rw------- 1 root root 3153 Oct 19 10:37 /tmp/data1

[after]
At subvol Snap1
At subvol Snap2
At subvol ../SnapY
-rw------- 1 root root 1492 Oct 19 10:39 /tmp/data1

Signed-off-by: Tsutomu Itoh <t-itoh@jp.fujitsu.com>
[ constify subvol argument, renamed single letter variables ]
Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
Tsutomu Itoh 2016-11-04 17:33:58 +09:00 committed by David Sterba
parent 45827710e2
commit 7d405df0da
1 changed files with 39 additions and 20 deletions

View File

@ -417,6 +417,37 @@ out:
return ret; return ret;
} }
static int set_root_info(struct btrfs_send *sctx, const char *subvol,
u64 *root_id)
{
int ret;
ret = init_root_path(sctx, subvol);
if (ret < 0)
goto out;
ret = get_root_id(sctx, subvol_strip_mountpoint(sctx->root_path, subvol),
root_id);
if (ret < 0) {
error("cannot resolve rootid for %s", subvol);
goto out;
}
out:
return ret;
}
static void free_send_info(struct btrfs_send *sctx)
{
if (sctx->mnt_fd >= 0) {
close(sctx->mnt_fd);
sctx->mnt_fd = -1;
}
free(sctx->root_path);
sctx->root_path = NULL;
subvol_uuid_search_finit(&sctx->sus);
}
int cmd_send(int argc, char **argv) int cmd_send(int argc, char **argv)
{ {
char *subvol = NULL; char *subvol = NULL;
@ -466,18 +497,10 @@ int cmd_send(int argc, char **argv)
goto out; goto out;
} }
ret = init_root_path(&send, subvol); ret = set_root_info(&send, subvol, &root_id);
if (ret < 0) if (ret < 0)
goto out; goto out;
ret = get_root_id(&send,
subvol_strip_mountpoint(send.root_path, subvol),
&root_id);
if (ret < 0) {
error("cannot resolve rootid for %s", subvol);
goto out;
}
ret = is_subvol_ro(&send, subvol); ret = is_subvol_ro(&send, subvol);
if (ret < 0) if (ret < 0)
goto out; goto out;
@ -492,15 +515,9 @@ int cmd_send(int argc, char **argv)
error("cannot add clone source: %s", strerror(-ret)); error("cannot add clone source: %s", strerror(-ret));
goto out; goto out;
} }
subvol_uuid_search_finit(&send.sus);
free(subvol); free(subvol);
subvol = NULL; subvol = NULL;
if (send.mnt_fd >= 0) { free_send_info(&send);
close(send.mnt_fd);
send.mnt_fd = -1;
}
free(send.root_path);
send.root_path = NULL;
full_send = 0; full_send = 0;
break; break;
case 'f': case 'f':
@ -657,6 +674,10 @@ int cmd_send(int argc, char **argv)
} }
if (!full_send && root_id) { if (!full_send && root_id) {
ret = set_root_info(&send, subvol, &root_id);
if (ret < 0)
goto out;
ret = find_good_parent(&send, root_id, &parent_root_id); ret = find_good_parent(&send, root_id, &parent_root_id);
if (ret < 0) { if (ret < 0) {
error("parent determination failed for %lld", error("parent determination failed for %lld",
@ -686,6 +707,7 @@ int cmd_send(int argc, char **argv)
error("cannot add clone source: %s", strerror(-ret)); error("cannot add clone source: %s", strerror(-ret));
goto out; goto out;
} }
free_send_info(&send);
} }
} }
@ -695,10 +717,7 @@ out:
free(subvol); free(subvol);
free(snapshot_parent); free(snapshot_parent);
free(send.clone_sources); free(send.clone_sources);
if (send.mnt_fd >= 0) free_send_info(&send);
close(send.mnt_fd);
free(send.root_path);
subvol_uuid_search_finit(&send.sus);
return !!ret; return !!ret;
} }