+ MSG(0, "\n");
+ break;
+ 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_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 +225,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))