btrfs-progs: receive: implement FILEATTR command
The initial proposal for file attributes was built on simply doing SETFLAGS but this builds on an old and non-extensible interface that has no direct mapping for all inode flags. There's a unified interface fileattr that covers file attributes and xflags, it should be possible to add new bits. On the protocol level the value is copied as-is in the original inode but this does not provide enough information how to apply the bits on the receiving side. Eg. IMMUTABLE flag prevents any changes to the file and has to be handled manually. The receiving side does not apply the bits yet, only parses it from the stream. Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
0353c83056
commit
ef719df5bb
|
@ -339,9 +339,9 @@ static int print_fallocate(const char *path, int mode, u64 offset, u64 len,
|
|||
mode, offset, len);
|
||||
}
|
||||
|
||||
static int print_setflags(const char *path, int flags, void *user)
|
||||
static int print_fileattr(const char *path, u64 attr, void *user)
|
||||
{
|
||||
return PRINT_DUMP(user, path, "setflags", "flags=%d", flags);
|
||||
return PRINT_DUMP(user, path, "fileattr", "fileattr=0x%llu", attr);
|
||||
}
|
||||
|
||||
struct btrfs_send_ops btrfs_print_send_ops = {
|
||||
|
@ -368,5 +368,5 @@ struct btrfs_send_ops btrfs_print_send_ops = {
|
|||
.update_extent = print_update_extent,
|
||||
.encoded_write = print_encoded_write,
|
||||
.fallocate = print_fallocate,
|
||||
.setflags = print_setflags,
|
||||
.fileattr = print_fileattr,
|
||||
};
|
||||
|
|
|
@ -1309,7 +1309,7 @@ static int process_fallocate(const char *path, int mode, u64 offset, u64 len,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int process_setflags(const char *path, int flags, void *user)
|
||||
static int process_fileattr(const char *path, u64 attr, void *user)
|
||||
{
|
||||
int ret;
|
||||
struct btrfs_receive *rctx = user;
|
||||
|
@ -1317,16 +1317,17 @@ static int process_setflags(const char *path, int flags, void *user)
|
|||
|
||||
ret = path_cat_out(full_path, rctx->full_subvol_path, path);
|
||||
if (ret < 0) {
|
||||
error("setflags: path invalid: %s", path);
|
||||
error("fileattr: path invalid: %s", path);
|
||||
return ret;
|
||||
}
|
||||
ret = open_inode_for_write(rctx, full_path);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = ioctl(rctx->write_fd, FS_IOC_SETFLAGS, &flags);
|
||||
ret = -EOPNOTSUPP;
|
||||
/* ret = ioctl(rctx->write_fd, FS_IOC_SETFLAGS, &flags); */
|
||||
if (ret < 0) {
|
||||
ret = -errno;
|
||||
error("setflags: setflags ioctl on %s failed: %m", path);
|
||||
error("fileattr: set file attributes on %s failed: %m", path);
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
|
@ -1356,7 +1357,7 @@ static struct btrfs_send_ops send_ops = {
|
|||
.update_extent = process_update_extent,
|
||||
.encoded_write = process_encoded_write,
|
||||
.fallocate = process_fallocate,
|
||||
.setflags = process_setflags,
|
||||
.fileattr = process_fileattr,
|
||||
};
|
||||
|
||||
static int do_receive(struct btrfs_receive *rctx, const char *tomnt,
|
||||
|
|
|
@ -372,10 +372,10 @@ static int read_and_process_cmd(struct btrfs_send_stream *sctx)
|
|||
u64 unencoded_file_len;
|
||||
u64 unencoded_len;
|
||||
u64 unencoded_offset;
|
||||
u64 fileattr;
|
||||
int len;
|
||||
int xattr_len;
|
||||
int fallocate_mode;
|
||||
int setflags_flags;
|
||||
|
||||
ret = read_cmd(sctx);
|
||||
if (ret)
|
||||
|
@ -548,10 +548,10 @@ static int read_and_process_cmd(struct btrfs_send_stream *sctx)
|
|||
ret = sctx->ops->fallocate(path, fallocate_mode, offset, tmp,
|
||||
sctx->user);
|
||||
break;
|
||||
case BTRFS_SEND_C_SETFLAGS:
|
||||
case BTRFS_SEND_C_FILEATTR:
|
||||
TLV_GET_STRING(sctx, BTRFS_SEND_A_PATH, &path);
|
||||
TLV_GET_U32(sctx, BTRFS_SEND_A_SETFLAGS_FLAGS, &setflags_flags);
|
||||
ret = sctx->ops->setflags(path, setflags_flags, sctx->user);
|
||||
TLV_GET_U32(sctx, BTRFS_SEND_A_FILEATTR, &fileattr);
|
||||
ret = sctx->ops->fileattr(path, fileattr, sctx->user);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ struct btrfs_send_ops {
|
|||
u32 encryption, void *user);
|
||||
int (*fallocate)(const char *path, int mode, u64 offset, u64 len,
|
||||
void *user);
|
||||
int (*setflags)(const char *path, int flags, void *user);
|
||||
int (*fileattr)(const char *path, u64 attr, void *user);
|
||||
};
|
||||
|
||||
int btrfs_read_and_process_send_stream(int fd,
|
||||
|
|
|
@ -98,7 +98,7 @@ enum btrfs_send_cmd {
|
|||
|
||||
/* Version 2 */
|
||||
BTRFS_SEND_C_FALLOCATE = 23,
|
||||
BTRFS_SEND_C_SETFLAGS = 24,
|
||||
BTRFS_SEND_C_FILEATTR = 24,
|
||||
BTRFS_SEND_C_ENCODED_WRITE = 25,
|
||||
BTRFS_SEND_C_MAX_V2 = 25,
|
||||
|
||||
|
@ -151,7 +151,13 @@ enum {
|
|||
/* Version 2 */
|
||||
BTRFS_SEND_A_FALLOCATE_MODE = 25,
|
||||
|
||||
BTRFS_SEND_A_SETFLAGS_FLAGS = 26,
|
||||
/*
|
||||
* File attributes from the FS_*_FL namespace (i_flags, xflags),
|
||||
* translated to BTRFS_INODE_* bits (BTRFS_INODE_FLAG_MASK) and stored
|
||||
* in btrfs_inode_item::flags (represented by btrfs_inode::flags and
|
||||
* btrfs_inode::ro_flags).
|
||||
*/
|
||||
BTRFS_SEND_A_FILEATTR = 26,
|
||||
|
||||
BTRFS_SEND_A_UNENCODED_FILE_LEN = 27,
|
||||
BTRFS_SEND_A_UNENCODED_LEN = 28,
|
||||
|
|
Loading…
Reference in New Issue