From 0edf1569717b6f29124fd771b6166dfda9b7e88a Mon Sep 17 00:00:00 2001 From: David Sterba Date: Aug 18 2020 16:46:52 +0000 Subject: btrfs-progs: move send-dump.c to cmds/receive-dump.c The dump is a command mode of receive. Signed-off-by: David Sterba --- diff --git a/Android.mk b/Android.mk index 21d0099..876e61f 100644 --- a/Android.mk +++ b/Android.mk @@ -22,7 +22,7 @@ objects := ctree.c disk-io.c kernel-lib/radix-tree.c extent-tree.c print-tree.c common/extent-cache.c extent_io.c volumes.c utils.c repair.c \ qgroup.c free-space-cache.c kernel-lib/list_sort.c props.c \ kernel-shared/ulist.c qgroup-verify.c backref.c common/string-table.c task-utils.c \ - inode.c file.c find-root.c free-space-tree.c help.c send-dump.c \ + inode.c file.c find-root.c free-space-tree.c help.c cmds/receive-dump.c \ common/fsfeatures.c kernel-lib/tables.c kernel-lib/raid56.c transaction.c cmds_objects := cmds-subvolume.c cmds-filesystem.c cmds-device.c cmds-scrub.c \ cmds-inspect.c cmds-balance.c cmds-send.c cmds-receive.c \ diff --git a/Makefile b/Makefile index ff5f60a..5bd120f 100644 --- a/Makefile +++ b/Makefile @@ -147,7 +147,7 @@ objects = kernel-shared/dir-item.o \ qgroup.o kernel-lib/list_sort.o props.o \ kernel-shared/ulist.o check/qgroup-verify.o kernel-shared/backref.o \ common/string-table.o common/task-utils.o \ - inode.o file.o find-root.o common/help.o send-dump.o \ + inode.o file.o find-root.o common/help.o cmds/receive-dump.o \ common/fsfeatures.o \ common/format-output.o \ common/device-utils.o diff --git a/cmds/receive-dump.c b/cmds/receive-dump.c new file mode 100644 index 0000000..0f84e43 --- /dev/null +++ b/cmds/receive-dump.c @@ -0,0 +1,341 @@ +/* + * Copyright (C) 2016 Fujitsu. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License v2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common/utils.h" +#include "cmds/commands.h" +#include "send-utils.h" +#include "send-stream.h" +#include "cmds/receive-dump.h" + +#define PATH_CAT_OR_RET(function_name, outpath, path1, path2, ret) \ +({ \ + ret = path_cat_out(outpath, path1, path2); \ + if (ret < 0) { \ + error("%s: path invalid: %s\n", function_name, path2); \ + return ret; \ + } \ +}) + +/* + * Print path and escape characters (in a C way) that could break the line. + * Returns the length of the escaped characters. Unprintable characters are + * escaped as octals. + */ +static int print_path_escaped(const char *path) +{ + size_t i; + size_t path_len = strlen(path); + int len = 0; + + for (i = 0; i < path_len; i++) { + char c = path[i]; + + len++; + switch (c) { + case '\a': putchar('\\'); putchar('a'); len++; break; + case '\b': putchar('\\'); putchar('b'); len++; break; + case '\e': putchar('\\'); putchar('e'); len++; break; + case '\f': putchar('\\'); putchar('f'); len++; break; + case '\n': putchar('\\'); putchar('n'); len++; break; + case '\r': putchar('\\'); putchar('r'); len++; break; + case '\t': putchar('\\'); putchar('t'); len++; break; + case '\v': putchar('\\'); putchar('v'); len++; break; + case ' ': putchar('\\'); putchar(' '); len++; break; + case '\\': putchar('\\'); putchar('\\'); len++; break; + default: + if (!isprint(c)) { + printf("\\%c%c%c", + '0' + ((c & 0300) >> 6), + '0' + ((c & 070) >> 3), + '0' + (c & 07)); + len += 3; + } else { + putchar(c); + } + } + } + return len; +} + +/* + * Underlying PRINT_DUMP, the only difference is how we handle + * the full path. + */ +__attribute__ ((format (printf, 5, 6))) +static int __print_dump(int subvol, void *user, const char *path, + const char *title, const char *fmt, ...) +{ + struct btrfs_dump_send_args *r = user; + char full_path[PATH_MAX] = {0}; + char *out_path; + va_list args; + int ret; + + if (subvol) { + PATH_CAT_OR_RET(title, r->full_subvol_path, r->root_path, path, ret); + out_path = r->full_subvol_path; + } else { + PATH_CAT_OR_RET(title, full_path, r->full_subvol_path, path, ret); + out_path = full_path; + } + + /* Unified header */ + printf("%-16s", title); + ret = print_path_escaped(out_path); + if (!fmt) { + putchar('\n'); + return 0; + } + /* Short paths are aligned to 32 chars; longer paths get a single space */ + do { + putchar(' '); + } while (++ret < 32); + va_start(args, fmt); + /* Operation specified ones */ + vprintf(fmt, args); + va_end(args); + putchar('\n'); + return 0; +} + +/* For subvolume/snapshot operation only */ +#define PRINT_DUMP_SUBVOL(user, path, title, fmt, ...) \ + __print_dump(1, user, path, title, fmt, ##__VA_ARGS__) + +/* For other operations */ +#define PRINT_DUMP(user, path, title, fmt, ...) \ + __print_dump(0, user, path, title, fmt, ##__VA_ARGS__) + +static int print_subvol(const char *path, const u8 *uuid, u64 ctransid, + void *user) +{ + char uuid_str[BTRFS_UUID_UNPARSED_SIZE]; + + uuid_unparse(uuid, uuid_str); + + return PRINT_DUMP_SUBVOL(user, path, "subvol", "uuid=%s transid=%llu", + uuid_str, ctransid); +} + +static int print_snapshot(const char *path, const u8 *uuid, u64 ctransid, + const u8 *parent_uuid, u64 parent_ctransid, + void *user) +{ + char uuid_str[BTRFS_UUID_UNPARSED_SIZE]; + char parent_uuid_str[BTRFS_UUID_UNPARSED_SIZE]; + int ret; + + uuid_unparse(uuid, uuid_str); + uuid_unparse(parent_uuid, parent_uuid_str); + + ret = PRINT_DUMP_SUBVOL(user, path, "snapshot", + "uuid=%s transid=%llu parent_uuid=%s parent_transid=%llu", + uuid_str, ctransid, parent_uuid_str, + parent_ctransid); + return ret; +} + +static int print_mkfile(const char *path, void *user) +{ + return PRINT_DUMP(user, path, "mkfile", NULL); +} + +static int print_mkdir(const char *path, void *user) +{ + return PRINT_DUMP(user, path, "mkdir", NULL); +} + +static int print_mknod(const char *path, u64 mode, u64 dev, void *user) +{ + return PRINT_DUMP(user, path, "mknod", "mode=%llo dev=0x%llx", mode, + dev); +} + +static int print_mkfifo(const char *path, void *user) +{ + return PRINT_DUMP(user, path, "mkfifo", NULL); +} + +static int print_mksock(const char *path, void *user) +{ + return PRINT_DUMP(user, path, "mksock", NULL); +} + +static int print_symlink(const char *path, const char *lnk, void *user) +{ + return PRINT_DUMP(user, path, "symlink", "dest=%s", lnk); +} + +static int print_rename(const char *from, const char *to, void *user) +{ + struct btrfs_dump_send_args *r = user; + char full_to[PATH_MAX]; + int ret; + + PATH_CAT_OR_RET("rename", full_to, r->full_subvol_path, to, ret); + return PRINT_DUMP(user, from, "rename", "dest=%s", full_to); +} + +static int print_link(const char *path, const char *lnk, void *user) +{ + return PRINT_DUMP(user, path, "link", "dest=%s", lnk); +} + +static int print_unlink(const char *path, void *user) +{ + return PRINT_DUMP(user, path, "unlink", NULL); +} + +static int print_rmdir(const char *path, void *user) +{ + return PRINT_DUMP(user, path, "rmdir", NULL); +} + +static int print_write(const char *path, const void *data, u64 offset, + u64 len, void *user) +{ + return PRINT_DUMP(user, path, "write", "offset=%llu len=%llu", + offset, len); +} + +static int print_clone(const char *path, u64 offset, u64 len, + const u8 *clone_uuid, u64 clone_ctransid, + const char *clone_path, u64 clone_offset, + void *user) +{ + struct btrfs_dump_send_args *r = user; + char full_path[PATH_MAX]; + int ret; + + PATH_CAT_OR_RET("clone", full_path, r->full_subvol_path, clone_path, + ret); + return PRINT_DUMP(user, path, "clone", + "offset=%llu len=%llu from=%s clone_offset=%llu", + offset, len, full_path, clone_offset); +} + +static int print_set_xattr(const char *path, const char *name, + const void *data, int len, void *user) +{ + return PRINT_DUMP(user, path, "set_xattr", "name=%s data=%.*s len=%d", + name, len, (char *)data, len); +} + +static int print_remove_xattr(const char *path, const char *name, void *user) +{ + + return PRINT_DUMP(user, path, "remove_xattr", "name=%s", name); +} + +static int print_truncate(const char *path, u64 size, void *user) +{ + return PRINT_DUMP(user, path, "truncate", "size=%llu", size); +} + +static int print_chmod(const char *path, u64 mode, void *user) +{ + return PRINT_DUMP(user, path, "chmod", "mode=%llo", mode); +} + +static int print_chown(const char *path, u64 uid, u64 gid, void *user) +{ + return PRINT_DUMP(user, path, "chown", "gid=%llu uid=%llu", gid, uid); +} + +static int sprintf_timespec(struct timespec *ts, char *dest, int max_size) +{ + struct tm tm; + int ret; + + if (!localtime_r(&ts->tv_sec, &tm)) { + error("failed to convert time %lld.%.9ld to local time", + (long long)ts->tv_sec, ts->tv_nsec); + return -EINVAL; + } + ret = strftime(dest, max_size, "%FT%T%z", &tm); + if (ret == 0) { + error( + "time %lld.%ld is too long to convert into readable string", + (long long)ts->tv_sec, ts->tv_nsec); + return -EINVAL; + } + return 0; +} + +#define TIME_STRING_MAX 64 +static int print_utimes(const char *path, struct timespec *at, + struct timespec *mt, struct timespec *ct, + void *user) +{ + char at_str[TIME_STRING_MAX]; + char mt_str[TIME_STRING_MAX]; + char ct_str[TIME_STRING_MAX]; + + if (sprintf_timespec(at, at_str, TIME_STRING_MAX - 1) < 0 || + sprintf_timespec(mt, mt_str, TIME_STRING_MAX - 1) < 0 || + sprintf_timespec(ct, ct_str, TIME_STRING_MAX - 1) < 0) + return -EINVAL; + return PRINT_DUMP(user, path, "utimes", "atime=%s mtime=%s ctime=%s", + at_str, mt_str, ct_str); +} + +static int print_update_extent(const char *path, u64 offset, u64 len, + void *user) +{ + return PRINT_DUMP(user, path, "update_extent", "offset=%llu len=%llu", + offset, len); +} + +struct btrfs_send_ops btrfs_print_send_ops = { + .subvol = print_subvol, + .snapshot = print_snapshot, + .mkfile = print_mkfile, + .mkdir = print_mkdir, + .mknod = print_mknod, + .mkfifo = print_mkfifo, + .mksock = print_mksock, + .symlink = print_symlink, + .rename = print_rename, + .link = print_link, + .unlink = print_unlink, + .rmdir = print_rmdir, + .write = print_write, + .clone = print_clone, + .set_xattr = print_set_xattr, + .remove_xattr = print_remove_xattr, + .truncate = print_truncate, + .chmod = print_chmod, + .chown = print_chown, + .utimes = print_utimes, + .update_extent = print_update_extent +}; diff --git a/cmds/receive-dump.h b/cmds/receive-dump.h new file mode 100644 index 0000000..06a6108 --- /dev/null +++ b/cmds/receive-dump.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2016 Fujitsu. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License v2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. + */ + +#ifndef __BTRFS_SEND_DUMP_H__ +#define __BTRFS_SEND_DUMP_H__ + +#include + +struct btrfs_dump_send_args { + char full_subvol_path[PATH_MAX]; + char root_path[PATH_MAX]; +}; + +extern struct btrfs_send_ops btrfs_print_send_ops; + +#endif diff --git a/cmds/receive.c b/cmds/receive.c index 1c3a40b..8ed73cc 100644 --- a/cmds/receive.c +++ b/cmds/receive.c @@ -49,7 +49,7 @@ #include "send.h" #include "send-stream.h" #include "send-utils.h" -#include "send-dump.h" +#include "cmds/receive-dump.h" #include "common/help.h" #include "common/path-utils.h" diff --git a/send-dump.c b/send-dump.c deleted file mode 100644 index 2f1bab2..0000000 --- a/send-dump.c +++ /dev/null @@ -1,341 +0,0 @@ -/* - * Copyright (C) 2016 Fujitsu. All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License v2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "common/utils.h" -#include "cmds/commands.h" -#include "send-utils.h" -#include "send-stream.h" -#include "send-dump.h" - -#define PATH_CAT_OR_RET(function_name, outpath, path1, path2, ret) \ -({ \ - ret = path_cat_out(outpath, path1, path2); \ - if (ret < 0) { \ - error("%s: path invalid: %s\n", function_name, path2); \ - return ret; \ - } \ -}) - -/* - * Print path and escape characters (in a C way) that could break the line. - * Returns the length of the escaped characters. Unprintable characters are - * escaped as octals. - */ -static int print_path_escaped(const char *path) -{ - size_t i; - size_t path_len = strlen(path); - int len = 0; - - for (i = 0; i < path_len; i++) { - char c = path[i]; - - len++; - switch (c) { - case '\a': putchar('\\'); putchar('a'); len++; break; - case '\b': putchar('\\'); putchar('b'); len++; break; - case '\e': putchar('\\'); putchar('e'); len++; break; - case '\f': putchar('\\'); putchar('f'); len++; break; - case '\n': putchar('\\'); putchar('n'); len++; break; - case '\r': putchar('\\'); putchar('r'); len++; break; - case '\t': putchar('\\'); putchar('t'); len++; break; - case '\v': putchar('\\'); putchar('v'); len++; break; - case ' ': putchar('\\'); putchar(' '); len++; break; - case '\\': putchar('\\'); putchar('\\'); len++; break; - default: - if (!isprint(c)) { - printf("\\%c%c%c", - '0' + ((c & 0300) >> 6), - '0' + ((c & 070) >> 3), - '0' + (c & 07)); - len += 3; - } else { - putchar(c); - } - } - } - return len; -} - -/* - * Underlying PRINT_DUMP, the only difference is how we handle - * the full path. - */ -__attribute__ ((format (printf, 5, 6))) -static int __print_dump(int subvol, void *user, const char *path, - const char *title, const char *fmt, ...) -{ - struct btrfs_dump_send_args *r = user; - char full_path[PATH_MAX] = {0}; - char *out_path; - va_list args; - int ret; - - if (subvol) { - PATH_CAT_OR_RET(title, r->full_subvol_path, r->root_path, path, ret); - out_path = r->full_subvol_path; - } else { - PATH_CAT_OR_RET(title, full_path, r->full_subvol_path, path, ret); - out_path = full_path; - } - - /* Unified header */ - printf("%-16s", title); - ret = print_path_escaped(out_path); - if (!fmt) { - putchar('\n'); - return 0; - } - /* Short paths are aligned to 32 chars; longer paths get a single space */ - do { - putchar(' '); - } while (++ret < 32); - va_start(args, fmt); - /* Operation specified ones */ - vprintf(fmt, args); - va_end(args); - putchar('\n'); - return 0; -} - -/* For subvolume/snapshot operation only */ -#define PRINT_DUMP_SUBVOL(user, path, title, fmt, ...) \ - __print_dump(1, user, path, title, fmt, ##__VA_ARGS__) - -/* For other operations */ -#define PRINT_DUMP(user, path, title, fmt, ...) \ - __print_dump(0, user, path, title, fmt, ##__VA_ARGS__) - -static int print_subvol(const char *path, const u8 *uuid, u64 ctransid, - void *user) -{ - char uuid_str[BTRFS_UUID_UNPARSED_SIZE]; - - uuid_unparse(uuid, uuid_str); - - return PRINT_DUMP_SUBVOL(user, path, "subvol", "uuid=%s transid=%llu", - uuid_str, ctransid); -} - -static int print_snapshot(const char *path, const u8 *uuid, u64 ctransid, - const u8 *parent_uuid, u64 parent_ctransid, - void *user) -{ - char uuid_str[BTRFS_UUID_UNPARSED_SIZE]; - char parent_uuid_str[BTRFS_UUID_UNPARSED_SIZE]; - int ret; - - uuid_unparse(uuid, uuid_str); - uuid_unparse(parent_uuid, parent_uuid_str); - - ret = PRINT_DUMP_SUBVOL(user, path, "snapshot", - "uuid=%s transid=%llu parent_uuid=%s parent_transid=%llu", - uuid_str, ctransid, parent_uuid_str, - parent_ctransid); - return ret; -} - -static int print_mkfile(const char *path, void *user) -{ - return PRINT_DUMP(user, path, "mkfile", NULL); -} - -static int print_mkdir(const char *path, void *user) -{ - return PRINT_DUMP(user, path, "mkdir", NULL); -} - -static int print_mknod(const char *path, u64 mode, u64 dev, void *user) -{ - return PRINT_DUMP(user, path, "mknod", "mode=%llo dev=0x%llx", mode, - dev); -} - -static int print_mkfifo(const char *path, void *user) -{ - return PRINT_DUMP(user, path, "mkfifo", NULL); -} - -static int print_mksock(const char *path, void *user) -{ - return PRINT_DUMP(user, path, "mksock", NULL); -} - -static int print_symlink(const char *path, const char *lnk, void *user) -{ - return PRINT_DUMP(user, path, "symlink", "dest=%s", lnk); -} - -static int print_rename(const char *from, const char *to, void *user) -{ - struct btrfs_dump_send_args *r = user; - char full_to[PATH_MAX]; - int ret; - - PATH_CAT_OR_RET("rename", full_to, r->full_subvol_path, to, ret); - return PRINT_DUMP(user, from, "rename", "dest=%s", full_to); -} - -static int print_link(const char *path, const char *lnk, void *user) -{ - return PRINT_DUMP(user, path, "link", "dest=%s", lnk); -} - -static int print_unlink(const char *path, void *user) -{ - return PRINT_DUMP(user, path, "unlink", NULL); -} - -static int print_rmdir(const char *path, void *user) -{ - return PRINT_DUMP(user, path, "rmdir", NULL); -} - -static int print_write(const char *path, const void *data, u64 offset, - u64 len, void *user) -{ - return PRINT_DUMP(user, path, "write", "offset=%llu len=%llu", - offset, len); -} - -static int print_clone(const char *path, u64 offset, u64 len, - const u8 *clone_uuid, u64 clone_ctransid, - const char *clone_path, u64 clone_offset, - void *user) -{ - struct btrfs_dump_send_args *r = user; - char full_path[PATH_MAX]; - int ret; - - PATH_CAT_OR_RET("clone", full_path, r->full_subvol_path, clone_path, - ret); - return PRINT_DUMP(user, path, "clone", - "offset=%llu len=%llu from=%s clone_offset=%llu", - offset, len, full_path, clone_offset); -} - -static int print_set_xattr(const char *path, const char *name, - const void *data, int len, void *user) -{ - return PRINT_DUMP(user, path, "set_xattr", "name=%s data=%.*s len=%d", - name, len, (char *)data, len); -} - -static int print_remove_xattr(const char *path, const char *name, void *user) -{ - - return PRINT_DUMP(user, path, "remove_xattr", "name=%s", name); -} - -static int print_truncate(const char *path, u64 size, void *user) -{ - return PRINT_DUMP(user, path, "truncate", "size=%llu", size); -} - -static int print_chmod(const char *path, u64 mode, void *user) -{ - return PRINT_DUMP(user, path, "chmod", "mode=%llo", mode); -} - -static int print_chown(const char *path, u64 uid, u64 gid, void *user) -{ - return PRINT_DUMP(user, path, "chown", "gid=%llu uid=%llu", gid, uid); -} - -static int sprintf_timespec(struct timespec *ts, char *dest, int max_size) -{ - struct tm tm; - int ret; - - if (!localtime_r(&ts->tv_sec, &tm)) { - error("failed to convert time %lld.%.9ld to local time", - (long long)ts->tv_sec, ts->tv_nsec); - return -EINVAL; - } - ret = strftime(dest, max_size, "%FT%T%z", &tm); - if (ret == 0) { - error( - "time %lld.%ld is too long to convert into readable string", - (long long)ts->tv_sec, ts->tv_nsec); - return -EINVAL; - } - return 0; -} - -#define TIME_STRING_MAX 64 -static int print_utimes(const char *path, struct timespec *at, - struct timespec *mt, struct timespec *ct, - void *user) -{ - char at_str[TIME_STRING_MAX]; - char mt_str[TIME_STRING_MAX]; - char ct_str[TIME_STRING_MAX]; - - if (sprintf_timespec(at, at_str, TIME_STRING_MAX - 1) < 0 || - sprintf_timespec(mt, mt_str, TIME_STRING_MAX - 1) < 0 || - sprintf_timespec(ct, ct_str, TIME_STRING_MAX - 1) < 0) - return -EINVAL; - return PRINT_DUMP(user, path, "utimes", "atime=%s mtime=%s ctime=%s", - at_str, mt_str, ct_str); -} - -static int print_update_extent(const char *path, u64 offset, u64 len, - void *user) -{ - return PRINT_DUMP(user, path, "update_extent", "offset=%llu len=%llu", - offset, len); -} - -struct btrfs_send_ops btrfs_print_send_ops = { - .subvol = print_subvol, - .snapshot = print_snapshot, - .mkfile = print_mkfile, - .mkdir = print_mkdir, - .mknod = print_mknod, - .mkfifo = print_mkfifo, - .mksock = print_mksock, - .symlink = print_symlink, - .rename = print_rename, - .link = print_link, - .unlink = print_unlink, - .rmdir = print_rmdir, - .write = print_write, - .clone = print_clone, - .set_xattr = print_set_xattr, - .remove_xattr = print_remove_xattr, - .truncate = print_truncate, - .chmod = print_chmod, - .chown = print_chown, - .utimes = print_utimes, - .update_extent = print_update_extent -}; diff --git a/send-dump.h b/send-dump.h deleted file mode 100644 index 06a6108..0000000 --- a/send-dump.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2016 Fujitsu. All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License v2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. - */ - -#ifndef __BTRFS_SEND_DUMP_H__ -#define __BTRFS_SEND_DUMP_H__ - -#include - -struct btrfs_dump_send_args { - char full_subvol_path[PATH_MAX]; - char root_path[PATH_MAX]; -}; - -extern struct btrfs_send_ops btrfs_print_send_ops; - -#endif