From 7935c4e1f0157ba321be08cf4ed1b8e40ec32507 Mon Sep 17 00:00:00 2001 From: Sheng Yong Date: Thu, 2 Nov 2017 11:56:07 +0800 Subject: [PATCH] dump.f2fs: introduce dump_xattr This patch introduces dump_xattr to create xattrs for dumped files. Signed-off-by: Sheng Yong Reviewed-by: Chao Yu [Jaegeuk Kim: detect header files] Signed-off-by: Jaegeuk Kim --- configure.ac | 4 +++- fsck/dump.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- fsck/fsck.h | 3 +++ fsck/xattr.c | 2 +- fsck/xattr.h | 9 +++++++- 5 files changed, 87 insertions(+), 6 deletions(-) diff --git a/configure.ac b/configure.ac index 2fc9260..e9dc4f4 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 \ + attr/xattr.h linux/xattr.h]) # Checks for typedefs, structures, and compiler characteristics. AC_C_INLINE @@ -106,6 +107,7 @@ AC_CHECK_FUNCS_ONCE([ fallocate getmntent memset + fsetxattr ]) AS_IF([test "$ac_cv_header_byteswap_h" = "yes"], diff --git a/fsck/dump.c b/fsck/dump.c index 128dc53..1b49e84 100644 --- a/fsck/dump.c +++ b/fsck/dump.c @@ -11,6 +11,13 @@ #include #include "fsck.h" +#include "xattr.h" +#ifdef HAVE_ATTR_XATTR_H +#include +#endif +#ifdef HAVE_LINUX_XATTR_H +#include +#endif #include #define BUF_SZ 80 @@ -310,15 +317,75 @@ static void dump_node_blk(struct f2fs_sb_info *sbi, int ntype, free(node_blk); } +#ifdef HAVE_FSETXATTR +static void dump_xattr(struct f2fs_sb_info *sbi, struct f2fs_node *node_blk) +{ + void *xattr; + struct f2fs_xattr_entry *ent; + char xattr_name[F2FS_NAME_LEN] = {0}; + int ret; + + xattr = read_all_xattrs(sbi, node_blk); + + list_for_each_xattr(ent, xattr) { + char *name = strndup(ent->e_name, ent->e_name_len); + void *value = ent->e_name + ent->e_name_len; + + if (!name) + continue; + + switch (ent->e_name_index) { + case F2FS_XATTR_INDEX_USER: + ret = snprintf(xattr_name, F2FS_NAME_LEN, "%s%s", + XATTR_USER_PREFIX, name); + break; + + case F2FS_XATTR_INDEX_SECURITY: + ret = snprintf(xattr_name, F2FS_NAME_LEN, "%s%s", + XATTR_SECURITY_PREFIX, name); + break; + case F2FS_XATTR_INDEX_TRUSTED: + ret = snprintf(xattr_name, F2FS_NAME_LEN, "%s%s", + XATTR_TRUSTED_PREFIX, name); + break; + default: + MSG(0, "Unknown xattr index 0x%x\n", ent->e_name_index); + free(name); + continue; + } + if (ret >= F2FS_NAME_LEN) { + MSG(0, "XATTR index 0x%x name too long\n", ent->e_name_index); + free(name); + continue; + } + + DBG(1, "fd %d xattr_name %s\n", c.dump_fd, xattr_name); + ret = fsetxattr(c.dump_fd, xattr_name, value, + le16_to_cpu(ent->e_value_size), 0); + if (ret) + MSG(0, "XATTR index 0x%x set xattr failed error %d\n", + ent->e_name_index, errno); + + free(name); + } + + free(xattr); +} +#else +static void dump_xattr(struct f2fs_sb_info *UNUSED(sbi), + struct f2fs_node *UNUSED(node_blk)) +{ + MSG(0, "XATTR does not support\n"); +} +#endif + static void dump_inode_blk(struct f2fs_sb_info *sbi, u32 nid, struct f2fs_node *node_blk) { u32 i = 0; u64 ofs = 0; - /* TODO: need to dump xattr */ - - if((node_blk->i.i_inline & F2FS_INLINE_DATA)){ + if((node_blk->i.i_inline & F2FS_INLINE_DATA)) { DBG(3, "ino[0x%x] has inline data!\n", nid); /* recover from inline data */ dev_write_dump(((unsigned char *)node_blk) + INLINE_DATA_OFFSET, @@ -345,6 +412,8 @@ static void dump_inode_blk(struct f2fs_sb_info *sbi, u32 nid, else ASSERT(0); } + + dump_xattr(sbi, node_blk); } static void dump_file(struct f2fs_sb_info *sbi, struct node_info *ni, diff --git a/fsck/fsck.h b/fsck/fsck.h index 1db5437..ec5ef06 100644 --- a/fsck/fsck.h +++ b/fsck/fsck.h @@ -244,4 +244,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/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..338d1cc 100644 --- a/fsck/xattr.h +++ b/fsck/xattr.h @@ -34,7 +34,14 @@ struct f2fs_xattr_entry { #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.7.4