mirror of
https://github.com/kdave/btrfs-progs
synced 2025-04-11 03:31:17 +00:00
btrfs-progs: receive: process fallocate commands
Send stream v2 can emit fallocate commands, so receive must support them as well. The implementation simply passes along the arguments to the syscall. Note that mode is encoded as a u32 in send stream but fallocate takes an int, so there is a unsigned->signed conversion there. Reviewed-by: Nikolay Borisov <nborisov@suse.com> Signed-off-by: Boris Burkov <boris@bur.io> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
d20e759fc9
commit
54db5c0397
@ -331,6 +331,14 @@ static int print_encoded_write(const char *path, const void *data, u64 offset,
|
||||
unencoded_offset, compression, encryption);
|
||||
}
|
||||
|
||||
static int print_fallocate(const char *path, int mode, u64 offset, u64 len,
|
||||
void *user)
|
||||
{
|
||||
return PRINT_DUMP(user, path, "fallocate",
|
||||
"mode=%d offset=%llu len=%llu",
|
||||
mode, offset, len);
|
||||
}
|
||||
|
||||
struct btrfs_send_ops btrfs_print_send_ops = {
|
||||
.subvol = print_subvol,
|
||||
.snapshot = print_snapshot,
|
||||
@ -354,4 +362,5 @@ struct btrfs_send_ops btrfs_print_send_ops = {
|
||||
.utimes = print_utimes,
|
||||
.update_extent = print_update_extent,
|
||||
.encoded_write = print_encoded_write,
|
||||
.fallocate = print_fallocate,
|
||||
};
|
||||
|
@ -1260,6 +1260,30 @@ static int process_encoded_write(const char *path, const void *data, u64 offset,
|
||||
compression);
|
||||
}
|
||||
|
||||
static int process_fallocate(const char *path, int mode, u64 offset, u64 len,
|
||||
void *user)
|
||||
{
|
||||
int ret;
|
||||
struct btrfs_receive *rctx = user;
|
||||
char full_path[PATH_MAX];
|
||||
|
||||
ret = path_cat_out(full_path, rctx->full_subvol_path, path);
|
||||
if (ret < 0) {
|
||||
error("fallocate: path invalid: %s", path);
|
||||
return ret;
|
||||
}
|
||||
ret = open_inode_for_write(rctx, full_path);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = fallocate(rctx->write_fd, mode, offset, len);
|
||||
if (ret < 0) {
|
||||
ret = -errno;
|
||||
error("fallocate: fallocate on %s failed: %m", path);
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct btrfs_send_ops send_ops = {
|
||||
.subvol = process_subvol,
|
||||
.snapshot = process_snapshot,
|
||||
@ -1283,6 +1307,7 @@ static struct btrfs_send_ops send_ops = {
|
||||
.utimes = process_utimes,
|
||||
.update_extent = process_update_extent,
|
||||
.encoded_write = process_encoded_write,
|
||||
.fallocate = process_fallocate,
|
||||
};
|
||||
|
||||
static int do_receive(struct btrfs_receive *rctx, const char *tomnt,
|
||||
|
@ -374,6 +374,7 @@ static int read_and_process_cmd(struct btrfs_send_stream *sctx)
|
||||
u64 unencoded_offset;
|
||||
int len;
|
||||
int xattr_len;
|
||||
int fallocate_mode;
|
||||
|
||||
ret = read_cmd(sctx);
|
||||
if (ret)
|
||||
@ -538,6 +539,14 @@ static int read_and_process_cmd(struct btrfs_send_stream *sctx)
|
||||
case BTRFS_SEND_C_END:
|
||||
ret = 1;
|
||||
break;
|
||||
case BTRFS_SEND_C_FALLOCATE:
|
||||
TLV_GET_STRING(sctx, BTRFS_SEND_A_PATH, &path);
|
||||
TLV_GET_U32(sctx, BTRFS_SEND_A_FALLOCATE_MODE, &fallocate_mode);
|
||||
TLV_GET_U64(sctx, BTRFS_SEND_A_FILE_OFFSET, &offset);
|
||||
TLV_GET_U64(sctx, BTRFS_SEND_A_SIZE, &tmp);
|
||||
ret = sctx->ops->fallocate(path, fallocate_mode, offset, tmp,
|
||||
sctx->user);
|
||||
break;
|
||||
}
|
||||
|
||||
tlv_get_failed:
|
||||
|
@ -57,6 +57,8 @@ struct btrfs_send_ops {
|
||||
u64 len, u64 unencoded_file_len, u64 unencoded_len,
|
||||
u64 unencoded_offset, u32 compression,
|
||||
u32 encryption, void *user);
|
||||
int (*fallocate)(const char *path, int mode, u64 offset, u64 len,
|
||||
void *user);
|
||||
};
|
||||
|
||||
int btrfs_read_and_process_send_stream(int fd,
|
||||
|
Loading…
Reference in New Issue
Block a user