On 11/03, Sheng Yong wrote: > This patch exports read_all_xattrs to allow dump/fsck to get all xattrs, > and introduces print_xattr_entry which tries to parse an xattr entry > accroding to its xattr index. > > Signed-off-by: Sheng Yong <shengyo...@huawei.com> > --- > v3->v5: > Please ignore the previous [PATCH v3/v4] because of the bad indent (some > configure of my email client may be not correct). Sorry for the noise :( > > v2->v3: > check if <linux/posix_acl.h> is supported. If it is not, print ACL value > in hex format. > > thanks, > Sheng > configure.ac | 3 +- > fsck/dump.c | 18 ++++---- > fsck/fsck.h | 7 +++- > fsck/mount.c | 132 > +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- > fsck/xattr.c | 2 +- > fsck/xattr.h | 54 +++++++++++++++++++++++- > 6 files changed, 199 insertions(+), 17 deletions(-) > > diff --git a/configure.ac b/configure.ac > index 2fc9260..91bbc9c 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -92,7 +92,8 @@ AS_IF([test "x$have_blkid" = "xyes"], > > # Checks for header files. > AC_CHECK_HEADERS([linux/fs.h linux/blkzoned.h fcntl.h mntent.h stdlib.h > string.h \ > - sys/ioctl.h sys/mount.h unistd.h linux/falloc.h byteswap.h]) > + sys/ioctl.h sys/mount.h unistd.h linux/falloc.h byteswap.h \ > + linux/posix_acl.h]) > > # Checks for typedefs, structures, and compiler characteristics. > AC_C_INLINE > diff --git a/fsck/dump.c b/fsck/dump.c > index 128dc53..90fd073 100644 > --- a/fsck/dump.c > +++ b/fsck/dump.c > @@ -419,17 +419,17 @@ void dump_node(struct f2fs_sb_info *sbi, nid_t nid, int > force) > if (le32_to_cpu(node_blk->footer.ino) == ni.ino && > le32_to_cpu(node_blk->footer.nid) == ni.nid && > ni.ino == ni.nid) { > - print_node_info(node_blk, force); > + print_node_info(sbi, node_blk, force); > dump_file(sbi, &ni, node_blk, force); > } else { > - print_node_info(node_blk, force); > + print_node_info(sbi, node_blk, force); > MSG(force, "Invalid (i)node block\n\n"); > } > > free(node_blk); > } > > -static void dump_node_from_blkaddr(u32 blk_addr) > +static void dump_node_from_blkaddr(struct f2fs_sb_info *sbi, u32 blk_addr) > { > struct f2fs_node *node_blk; > int ret; > @@ -441,9 +441,9 @@ static void dump_node_from_blkaddr(u32 blk_addr) > ASSERT(ret >= 0); > > if (c.dbg_lv > 0) > - print_node_info(node_blk, 0); > + print_node_info(sbi, node_blk, 0); > else > - print_inode_info(&node_blk->i, 1); > + print_inode_info(sbi, node_blk, 1); > > free(node_blk); > } > @@ -567,7 +567,7 @@ int dump_info_from_blkaddr(struct f2fs_sb_info *sbi, u32 > blk_addr) > > /* print inode */ > if (c.dbg_lv > 0) > - dump_node_from_blkaddr(ino_ni.blk_addr); > + dump_node_from_blkaddr(sbi, ino_ni.blk_addr); > > if (type == SEG_TYPE_CUR_DATA || type == SEG_TYPE_DATA) { > MSG(0, "FS Userdata Area: Data block from 0x%x\n", blk_addr); > @@ -575,7 +575,7 @@ int dump_info_from_blkaddr(struct f2fs_sb_info *sbi, u32 > blk_addr) > nid, ni.blk_addr); > MSG(0, " - Inode block : id = 0x%x from 0x%x\n", > ni.ino, ino_ni.blk_addr); > - dump_node_from_blkaddr(ino_ni.blk_addr); > + dump_node_from_blkaddr(sbi, ino_ni.blk_addr); > dump_data_offset(ni.blk_addr, > le16_to_cpu(sum_entry.ofs_in_node)); > } else { > @@ -583,13 +583,13 @@ int dump_info_from_blkaddr(struct f2fs_sb_info *sbi, > u32 blk_addr) > if (ni.ino == ni.nid) { > MSG(0, " - Inode block : id = 0x%x from 0x%x\n", > ni.ino, ino_ni.blk_addr); > - dump_node_from_blkaddr(ino_ni.blk_addr); > + dump_node_from_blkaddr(sbi, ino_ni.blk_addr); > } else { > MSG(0, " - Node block : id = 0x%x from 0x%x\n", > nid, ni.blk_addr); > MSG(0, " - Inode block : id = 0x%x from 0x%x\n", > ni.ino, ino_ni.blk_addr); > - dump_node_from_blkaddr(ino_ni.blk_addr); > + dump_node_from_blkaddr(sbi, ino_ni.blk_addr); > dump_node_offset(ni.blk_addr); > } > } > diff --git a/fsck/fsck.h b/fsck/fsck.h > index 1e8ed0b..f8caa46 100644 > --- a/fsck/fsck.h > +++ b/fsck/fsck.h > @@ -141,8 +141,8 @@ int convert_encrypted_name(unsigned char *, int, unsigned > char *, int); > > extern void update_free_segments(struct f2fs_sb_info *); > void print_cp_state(u32); > -extern void print_node_info(struct f2fs_node *, int); > -extern void print_inode_info(struct f2fs_inode *, int); > +extern void print_node_info(struct f2fs_sb_info *, struct f2fs_node *, int); > +extern void print_inode_info(struct f2fs_sb_info *, struct f2fs_node *, int); > extern struct seg_entry *get_seg_entry(struct f2fs_sb_info *, unsigned int); > extern struct f2fs_summary_block *get_sum_block(struct f2fs_sb_info *, > unsigned int, int *); > @@ -228,4 +228,7 @@ int f2fs_symlink(struct f2fs_sb_info *, struct dentry *); > int inode_set_selinux(struct f2fs_sb_info *, u32, const char *); > int f2fs_find_path(struct f2fs_sb_info *, char *, nid_t *); > > +/* xattr.c */ > +void *read_all_xattrs(struct f2fs_sb_info *, struct f2fs_node *); > + > #endif /* _FSCK_H_ */ > diff --git a/fsck/mount.c b/fsck/mount.c > index d8bc50c..c453582 100644 > --- a/fsck/mount.c > +++ b/fsck/mount.c > @@ -9,7 +9,9 @@ > * published by the Free Software Foundation. > */ > #include "fsck.h" > +#include "xattr.h" > #include <locale.h> > +#include <linux/posix_acl.h>
Still build failure. We can use <sys/acl.h> > > u32 get_free_segments(struct f2fs_sb_info *sbi) > { > @@ -35,8 +37,125 @@ void update_free_segments(struct f2fs_sb_info *sbi) > i++; > } > > -void print_inode_info(struct f2fs_inode *inode, int name) > +#ifdef HAVE_LINUX_POSIX_ACL_H > +void print_acl(char *value, int size) > { > + struct f2fs_acl_header *hdr = (struct f2fs_acl_header *)value; > + struct f2fs_acl_entry *entry = (struct f2fs_acl_entry *)(hdr + 1); > + const char *end = value + size; > + int i, count; > + > + if (hdr->a_version != cpu_to_le32(F2FS_ACL_VERSION)) { > + MSG(0, "Invalid ACL version [0x%x : 0x%x]\n", > + le32_to_cpu(hdr->a_version), F2FS_ACL_VERSION); > + return; > + } > + > + count = f2fs_acl_count(size); > + if (count <= 0) { > + MSG(0, "Invalid ACL value size %d\n", size); > + return; > + } > + > + for (i = 0; i < count; i++) { > + if ((char *)entry > end) { > + MSG(0, "Invalid ACL entries count %d\n", count); > + return; > + } > + > + switch (le16_to_cpu(entry->e_tag)) { > + case ACL_USER_OBJ: > + case ACL_GROUP_OBJ: > + case ACL_MASK: > + case ACL_OTHER: > + MSG(0, "tag:0x%x perm:0x%x\n", > + le16_to_cpu(entry->e_tag), > + le16_to_cpu(entry->e_perm)); > + entry = (struct f2fs_acl_entry *)((char *)entry + > + sizeof(struct f2fs_acl_entry_short)); > + break; > + case ACL_USER: > + MSG(0, "tag:0x%x perm:0x%x uid:%u\n", > + le16_to_cpu(entry->e_tag), > + le16_to_cpu(entry->e_perm), > + le32_to_cpu(entry->e_id)); > + entry = (struct f2fs_acl_entry *)((char *)entry + > + sizeof(struct f2fs_acl_entry)); > + break; > + case ACL_GROUP: > + MSG(0, "tag:0x%x perm:0x%x gid:%u\n", > + le16_to_cpu(entry->e_tag), > + le16_to_cpu(entry->e_perm), > + le32_to_cpu(entry->e_id)); > + entry = (struct f2fs_acl_entry *)((char *)entry + > + sizeof(struct f2fs_acl_entry)); > + break; > + default: > + MSG(0, "Unknown ACL tag 0x%x\n", > + le16_to_cpu(entry->e_tag)); > + return; > + } > + } > +} > +#else > +#define print_acl(value, size) do { \ > + int i; \ > + for (i = 0; i < size; i++) \ > + MSG(0, "%02X", value[i]); \ > + MSG(0, "\n"); \ > +} while (0) > +#endif > + > +void print_xattr_entry(struct f2fs_xattr_entry *ent) > +{ > + char *value = (char *)(ent->e_name + le16_to_cpu(ent->e_name_len)); > + struct fscrypt_context *ctx; > + int i; > + > + MSG(0, "\nxattr: e_name_index:%d e_name:", ent->e_name_index); > + for (i = 0; i < le16_to_cpu(ent->e_name_len); i++) > + MSG(0, "%c", ent->e_name[i]); > + MSG(0, " e_name_len:%d e_value_size:%d e_value:\n", > + ent->e_name_len, le16_to_cpu(ent->e_value_size)); > + > + switch (ent->e_name_index) { > + case F2FS_XATTR_INDEX_POSIX_ACL_ACCESS: > + case F2FS_XATTR_INDEX_POSIX_ACL_DEFAULT: > + print_acl(value, le16_to_cpu(ent->e_value_size)); > + break; > + case F2FS_XATTR_INDEX_USER: > + case F2FS_XATTR_INDEX_SECURITY: > + case F2FS_XATTR_INDEX_TRUSTED: > + case F2FS_XATTR_INDEX_LUSTRE: > + for (i = 0; i < le16_to_cpu(ent->e_value_size); i++) > + MSG(0, "%02X", value[i]); > + MSG(0, "\n"); > + break; > + case F2FS_XATTR_INDEX_ENCRYPTION: > + ctx = (struct fscrypt_context *)value; > + MSG(0, "format: %d\n", ctx->format); > + MSG(0, "contents_encryption_mode: 0x%x\n", > ctx->contents_encryption_mode); > + MSG(0, "filenames_encryption_mode: 0x%x\n", > ctx->filenames_encryption_mode); > + MSG(0, "flags: 0x%x\n", ctx->flags); > + MSG(0, "master_key_descriptor: "); > + for (i = 0; i < FS_KEY_DESCRIPTOR_SIZE; i++) > + MSG(0, "%02X", ctx->master_key_descriptor[i]); > + MSG(0, "\nnonce: "); > + for (i = 0; i < FS_KEY_DERIVATION_NONCE_SIZE; i++) > + MSG(0, "%02X", ctx->nonce[i]); > + MSG(0, "\n"); > + break; > + default: > + break; > + } > +} > + > +void print_inode_info(struct f2fs_sb_info *sbi, > + struct f2fs_node *node, int name) > +{ > + struct f2fs_inode *inode = &node->i; > + void *xattr_addr; > + struct f2fs_xattr_entry *ent; > unsigned char en[F2FS_NAME_LEN + 1]; > unsigned int i = 0; > int namelen = le32_to_cpu(inode->i_namelen); > @@ -111,17 +230,24 @@ void print_inode_info(struct f2fs_inode *inode, int > name) > DISP_u32(inode, i_nid[3]); /* indirect */ > DISP_u32(inode, i_nid[4]); /* double indirect */ > > + xattr_addr = read_all_xattrs(sbi, node); > + list_for_each_xattr(ent, xattr_addr) { > + print_xattr_entry(ent); > + } > + free(xattr_addr); > + > printf("\n"); > } > > -void print_node_info(struct f2fs_node *node_block, int verbose) > +void print_node_info(struct f2fs_sb_info *sbi, > + struct f2fs_node *node_block, int verbose) > { > nid_t ino = le32_to_cpu(node_block->footer.ino); > nid_t nid = le32_to_cpu(node_block->footer.nid); > /* Is this inode? */ > if (ino == nid) { > DBG(verbose, "Node ID [0x%x:%u] is inode\n", nid, nid); > - print_inode_info(&node_block->i, verbose); > + print_inode_info(sbi, node_block, verbose); > } else { > int i; > u32 *dump_blk = (u32 *)node_block; > diff --git a/fsck/xattr.c b/fsck/xattr.c > index 3f5c7d3..1d0f7d3 100644 > --- a/fsck/xattr.c > +++ b/fsck/xattr.c > @@ -20,7 +20,7 @@ > #define XATTR_CREATE 0x1 > #define XATTR_REPLACE 0x2 > > -static void *read_all_xattrs(struct f2fs_sb_info *sbi, struct f2fs_node > *inode) > +void *read_all_xattrs(struct f2fs_sb_info *sbi, struct f2fs_node *inode) > { > struct f2fs_xattr_header *header; > void *txattr_addr; > diff --git a/fsck/xattr.h b/fsck/xattr.h > index b414629..beed3bb 100644 > --- a/fsck/xattr.h > +++ b/fsck/xattr.h > @@ -31,10 +31,62 @@ struct f2fs_xattr_entry { > char e_name[0]; /* attribute name */ > }; > > +#define FS_KEY_DESCRIPTOR_SIZE 8 > +#define FS_KEY_DERIVATION_NONCE_SIZE 16 > + > +struct fscrypt_context { > + u8 format; > + u8 contents_encryption_mode; > + u8 filenames_encryption_mode; > + u8 flags; > + u8 master_key_descriptor[FS_KEY_DESCRIPTOR_SIZE]; > + u8 nonce[FS_KEY_DERIVATION_NONCE_SIZE]; > +} __attribute__((packed)); > + > +#define F2FS_ACL_VERSION 0x0001 > + > +struct f2fs_acl_entry { > + __le16 e_tag; > + __le16 e_perm; > + __le32 e_id; > +}; > + > +struct f2fs_acl_entry_short { > + __le16 e_tag; > + __le16 e_perm; > +}; > + > +struct f2fs_acl_header { > + __le32 a_version; > +}; > + > +static inline int f2fs_acl_count(int size) > +{ > + ssize_t s; > + size -= sizeof(struct f2fs_acl_header); > + s = size - 4 * sizeof(struct f2fs_acl_entry_short); > + if (s < 0) { > + if (size % sizeof(struct f2fs_acl_entry_short)) > + return -1; > + return size / sizeof(struct f2fs_acl_entry_short); > + } else { > + if (s % sizeof(struct f2fs_acl_entry)) > + return -1; > + return s / sizeof(struct f2fs_acl_entry) + 4; > + } > +} > + > #define XATTR_ROUND (3) > > #define XATTR_SELINUX_SUFFIX "selinux" > -#define F2FS_XATTR_INDEX_SECURITY 6 > +#define F2FS_XATTR_INDEX_USER 1 > +#define F2FS_XATTR_INDEX_POSIX_ACL_ACCESS 2 > +#define F2FS_XATTR_INDEX_POSIX_ACL_DEFAULT 3 > +#define F2FS_XATTR_INDEX_TRUSTED 4 > +#define F2FS_XATTR_INDEX_LUSTRE 5 > +#define F2FS_XATTR_INDEX_SECURITY 6 > +#define F2FS_XATTR_INDEX_ENCRYPTION 9 > + > #define IS_XATTR_LAST_ENTRY(entry) (*(__u32 *)(entry) == 0) > > #define XATTR_HDR(ptr) ((struct f2fs_xattr_header *)(ptr)) > -- > 2.11.0 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel