Messages in this thread Patch in this message | | | From | Sheng Yong <> | Subject | [PATCH 1/2] f2fs_io: add [get|set_attr] to access inode extra attributes | Date | Mon, 29 May 2023 09:35:01 +0800 |
| |
This patch adds get_attr and set_attr to access inode's extra attributes.
Signed-off-by: Sheng Yong <shengyong@oppo.com> --- tools/f2fs_io/f2fs_io.c | 165 ++++++++++++++++++++++++++++++++++++++++ tools/f2fs_io/f2fs_io.h | 34 +++++++++ 2 files changed, 199 insertions(+)
diff --git a/tools/f2fs_io/f2fs_io.c b/tools/f2fs_io/f2fs_io.c index 5bc0baf..70e0347 100644 --- a/tools/f2fs_io/f2fs_io.c +++ b/tools/f2fs_io/f2fs_io.c @@ -1311,6 +1311,169 @@ static void do_gc(int argc, char **argv, const struct cmd_desc *cmd) exit(0); } +#define get_attr_desc "get inode extra attribute" +#define get_attr_help "f2fs_io get_attr [field] [file_path]\n\n" \ +"field can be\n" \ +" total_size\n" \ +" isize\n" \ +" inline_xattr_size\n" \ +" projid\n" \ +" inode_chksum\n" \ +" crtime\n" \ +" cblocks\n" \ +" coption\n" + +static const char *extra_attr_fields[] = { + [F2FS_EXTRA_ATTR_TOTAL_SIZE] = "total_size", + [F2FS_EXTRA_ATTR_ISIZE] = "isize", + [F2FS_EXTRA_ATTR_INLINE_XATTR_SIZE] = "inline_xattr_size", + [F2FS_EXTRA_ATTR_PROJID] = "projid", + [F2FS_EXTRA_ATTR_INODE_CHKSUM] = "inode_chksum", + [F2FS_EXTRA_ATTR_CRTIME] = "crtime", + [F2FS_EXTRA_ATTR_COMPR_BLOCKS] = "cblocks", + [F2FS_EXTRA_ATTR_COMPR_OPTION] = "coption", +}; + +static void do_get_attr(int argc, char **argv, const struct cmd_desc *cmd) +{ + struct f2fs_extra_attr attr = {0}; + struct timespec ts = {0}; + struct f2fs_comp_option_v2 coption = {0}; + int ret, fd; + + if (argc != 3) { + fputs("Excess arguments\n\n", stderr); + fputs(cmd->cmd_help, stderr); + exit(1); + } + + for (attr.field = 0; attr.field < F2FS_EXTRA_ATTR_MAX; attr.field++) { + if (!strcmp(extra_attr_fields[attr.field], argv[1])) + break; + } + + switch (attr.field) { + case F2FS_EXTRA_ATTR_TOTAL_SIZE: + case F2FS_EXTRA_ATTR_ISIZE: + case F2FS_EXTRA_ATTR_INLINE_XATTR_SIZE: + case F2FS_EXTRA_ATTR_PROJID: + case F2FS_EXTRA_ATTR_INODE_CHKSUM: + case F2FS_EXTRA_ATTR_COMPR_BLOCKS: + attr.attr_size = sizeof(attr.attr); + break; + case F2FS_EXTRA_ATTR_CRTIME: + attr.attr_size = sizeof(ts); + attr.attr = (unsigned long)&ts; + break; + case F2FS_EXTRA_ATTR_COMPR_OPTION: + attr.attr_size = sizeof(coption); + attr.attr = (unsigned long)&coption; + break; + default: + die("Unknown field"); + } + + fd = xopen(argv[2], O_RDONLY, 0); + + ret = ioctl(fd, F2FS_IOC_GET_EXTRA_ATTR, &attr); + if (ret < 0) + die_errno("F2FS_IOC_GET_EXTRA_ATTR failed"); + + switch (attr.field) { + case F2FS_EXTRA_ATTR_TOTAL_SIZE: + case F2FS_EXTRA_ATTR_ISIZE: + case F2FS_EXTRA_ATTR_INLINE_XATTR_SIZE: + case F2FS_EXTRA_ATTR_PROJID: + case F2FS_EXTRA_ATTR_COMPR_BLOCKS: + printf("%"PRIu64"\n", attr.attr); + break; + case F2FS_EXTRA_ATTR_INODE_CHKSUM: + printf("0x%"PRIx64"\n", attr.attr); + break; + case F2FS_EXTRA_ATTR_CRTIME: + printf("sec: %lu\nnsec: %lu\n", ts.tv_sec, ts.tv_nsec); + break; + case F2FS_EXTRA_ATTR_COMPR_OPTION: + printf("compression algorithm:%u\n", coption.algorithm); + printf("compression cluster log size:%u\n", coption.log_cluster_size); + printf("compression level:%u\n", coption.level); + printf("compression flag:0x%x\n", coption.flag); + break; + default: + die("Unknown field"); + } + + exit(0); +} + +#define set_attr_desc "set inode extra attribute" +#define set_attr_help "f2fs_io set_attr [field] [values] [file_path]\n\n" \ +"field can be\n" \ +" inline_xattr_size : [values] is [size]\n" \ +" coption : [values] are [algorithm] [log_cluster_size] [level] [flag]\n" \ +" algorithm : compression algorithm (0:lzo, 1: lz4, 2:zstd, 3:lzorle)\n" \ +" log_cluster_size : compression cluster log size (2 <= log_size <= 8)\n" \ +" level : compression level\n" \ +" flag : compression flag (1:chksum)\n" + +static void do_set_attr(int argc, char **argv, const struct cmd_desc *cmd) +{ + struct f2fs_extra_attr attr = {0}; + struct f2fs_comp_option_v2 coption = {0}; + int i; + int ret, fd; + + if (argc < 4) + goto out; + + if (!strcmp(argv[1], extra_attr_fields[F2FS_EXTRA_ATTR_INLINE_XATTR_SIZE])) { + if (argc != 4) + goto out; + i = 2; + attr.field = F2FS_EXTRA_ATTR_INLINE_XATTR_SIZE; + attr.attr_size = sizeof(attr.attr); + attr.attr = atoi(argv[i++]); + } else if (!strcmp(argv[1], extra_attr_fields[F2FS_EXTRA_ATTR_COMPR_OPTION])) { + if (argc != 7) + goto out; + i = 2; + coption.algorithm = atoi(argv[i++]); + coption.log_cluster_size = atoi(argv[i++]); + coption.level = atoi(argv[i++]); + coption.flag = atoi(argv[i++]); + attr.field = F2FS_EXTRA_ATTR_COMPR_OPTION; + attr.attr_size = sizeof(coption); + attr.attr = (unsigned long)&coption; + } else { + die("Unknown or read only field"); + } + + fd = xopen(argv[i], O_WRONLY, 0); + + ret = ioctl(fd, F2FS_IOC_SET_EXTRA_ATTR, &attr); + if (ret < 0) + die_errno("F2FS_IOC_SET_EXTRA_ATTR failed"); + + switch (attr.field) { + case F2FS_EXTRA_ATTR_INLINE_XATTR_SIZE: + printf("set inline_xattr_size:%"PRIu64"\n", attr.attr); + break; + case F2FS_EXTRA_ATTR_COMPR_OPTION: + printf("set compression option: algorithm=%u, " + "log_cluster_size=%u, level=%u, flag=0x%x\n", + coption.algorithm, coption.log_cluster_size, + coption.level, coption.flag); + break; + } + + exit(0); +out: + fputs("Excess arguments\n\n", stderr); + fputs(cmd->cmd_help, stderr); + exit(1); +} + + #define CMD_HIDDEN 0x0001 #define CMD(name) { #name, do_##name, name##_desc, name##_help, 0 } #define _CMD(name) { #name, do_##name, NULL, NULL, CMD_HIDDEN } @@ -1343,6 +1506,8 @@ const struct cmd_desc cmd_list[] = { CMD(get_filename_encrypt_mode), CMD(rename), CMD(gc), + CMD(get_attr), + CMD(set_attr), { NULL, NULL, NULL, NULL, 0 } }; diff --git a/tools/f2fs_io/f2fs_io.h b/tools/f2fs_io/f2fs_io.h index 58be8f8..b0be15c 100644 --- a/tools/f2fs_io/f2fs_io.h +++ b/tools/f2fs_io/f2fs_io.h @@ -91,6 +91,10 @@ typedef u32 __be32; #define F2FS_IOC_DECOMPRESS_FILE _IO(F2FS_IOCTL_MAGIC, 23) #define F2FS_IOC_COMPRESS_FILE _IO(F2FS_IOCTL_MAGIC, 24) #define F2FS_IOC_START_ATOMIC_REPLACE _IO(F2FS_IOCTL_MAGIC, 25) +#define F2FS_IOC_GET_EXTRA_ATTR _IOR(F2FS_IOCTL_MAGIC, 26, \ + struct f2fs_extra_attr) +#define F2FS_IOC_SET_EXTRA_ATTR _IOW(F2FS_IOCTL_MAGIC, 27, \ + struct f2fs_extra_attr) #ifndef FSCRYPT_POLICY_V1 #define FSCRYPT_POLICY_V1 0 @@ -216,3 +220,33 @@ struct f2fs_comp_option { u8 algorithm; u8 log_cluster_size; }; + +struct f2fs_comp_option_v2 { + u8 algorithm; + u8 log_cluster_size; + u8 level; + u8 flag; +}; + +enum { + F2FS_EXTRA_ATTR_TOTAL_SIZE, /* ro, size of extra attr area */ + F2FS_EXTRA_ATTR_ISIZE, /* ro, i_extra_isize */ + F2FS_EXTRA_ATTR_INLINE_XATTR_SIZE, /* r2, i_inline_xattr_size */ + F2FS_EXTRA_ATTR_PROJID, /* ro, i_projid */ + F2FS_EXTRA_ATTR_INODE_CHKSUM, /* ro, i_inode_chksum */ + F2FS_EXTRA_ATTR_CRTIME, /* ro, i_crtime, i_crtime_nsec */ + F2FS_EXTRA_ATTR_COMPR_BLOCKS, /* ro, i_compr_blocks */ + F2FS_EXTRA_ATTR_COMPR_OPTION, /* rw, i_compress_algorithm, + * i_log_cluster_size, + * i_compress_flag + */ + F2FS_EXTRA_ATTR_MAX, +}; + +struct f2fs_extra_attr { + u8 field; /* F2FS_EXTRA_ATTR_* */ + u8 rsvd1; + u16 attr_size; /* size of @attr */ + u32 rsvd2; + u64 attr; /* attr value or pointer */ +}; -- 2.40.1
| |