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

Reply via email to