|
@@ -64,6 +64,7 @@
|
|
#define OCFS2_INODE_SIGNATURE "INODE01"
|
|
#define OCFS2_INODE_SIGNATURE "INODE01"
|
|
#define OCFS2_EXTENT_BLOCK_SIGNATURE "EXBLK01"
|
|
#define OCFS2_EXTENT_BLOCK_SIGNATURE "EXBLK01"
|
|
#define OCFS2_GROUP_DESC_SIGNATURE "GROUP01"
|
|
#define OCFS2_GROUP_DESC_SIGNATURE "GROUP01"
|
|
|
|
+#define OCFS2_XATTR_BLOCK_SIGNATURE "XATTR01"
|
|
|
|
|
|
/* Compatibility flags */
|
|
/* Compatibility flags */
|
|
#define OCFS2_HAS_COMPAT_FEATURE(sb,mask) \
|
|
#define OCFS2_HAS_COMPAT_FEATURE(sb,mask) \
|
|
@@ -715,6 +716,123 @@ struct ocfs2_group_desc
|
|
/*40*/ __u8 bg_bitmap[0];
|
|
/*40*/ __u8 bg_bitmap[0];
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+/*
|
|
|
|
+ * On disk extended attribute structure for OCFS2.
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * ocfs2_xattr_entry indicates one extend attribute.
|
|
|
|
+ *
|
|
|
|
+ * Note that it can be stored in inode, one block or one xattr bucket.
|
|
|
|
+ */
|
|
|
|
+struct ocfs2_xattr_entry {
|
|
|
|
+ __le32 xe_name_hash; /* hash value of xattr prefix+suffix. */
|
|
|
|
+ __le16 xe_name_offset; /* byte offset from the 1st etnry in the local
|
|
|
|
+ local xattr storage(inode, xattr block or
|
|
|
|
+ xattr bucket). */
|
|
|
|
+ __u8 xe_name_len; /* xattr name len, does't include prefix. */
|
|
|
|
+ __u8 xe_type; /* the low 7 bits indicates the name prefix's
|
|
|
|
+ * type and the highest 1 bits indicate whether
|
|
|
|
+ * the EA is stored in the local storage. */
|
|
|
|
+ __le64 xe_value_size; /* real xattr value length. */
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * On disk structure for xattr header.
|
|
|
|
+ *
|
|
|
|
+ * One ocfs2_xattr_header describes how many ocfs2_xattr_entry records in
|
|
|
|
+ * the local xattr storage.
|
|
|
|
+ */
|
|
|
|
+struct ocfs2_xattr_header {
|
|
|
|
+ __le16 xh_count; /* contains the count of how
|
|
|
|
+ many records are in the
|
|
|
|
+ local xattr storage. */
|
|
|
|
+ __le16 xh_reserved1;
|
|
|
|
+ __le32 xh_reserved2;
|
|
|
|
+ __le64 xh_csum;
|
|
|
|
+ struct ocfs2_xattr_entry xh_entries[0]; /* xattr entry list. */
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * On disk structure for xattr value root.
|
|
|
|
+ *
|
|
|
|
+ * It is used when one extended attribute's size is larger, and we will save it
|
|
|
|
+ * in an outside cluster. It will stored in a b-tree like file content.
|
|
|
|
+ */
|
|
|
|
+struct ocfs2_xattr_value_root {
|
|
|
|
+/*00*/ __le32 xr_clusters; /* clusters covered by xattr value. */
|
|
|
|
+ __le32 xr_reserved0;
|
|
|
|
+ __le64 xr_last_eb_blk; /* Pointer to last extent block */
|
|
|
|
+/*10*/ struct ocfs2_extent_list xr_list; /* Extent record list */
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * On disk structure for xattr tree root.
|
|
|
|
+ *
|
|
|
|
+ * It is used when there are too many extended attributes for one file. These
|
|
|
|
+ * attributes will be organized and stored in an indexed-btree.
|
|
|
|
+ */
|
|
|
|
+struct ocfs2_xattr_tree_root {
|
|
|
|
+/*00*/ __le32 xt_clusters; /* clusters covered by xattr. */
|
|
|
|
+ __le32 xt_reserved0;
|
|
|
|
+ __le64 xt_last_eb_blk; /* Pointer to last extent block */
|
|
|
|
+/*10*/ struct ocfs2_extent_list xt_list; /* Extent record list */
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+#define OCFS2_XATTR_INDEXED 0x1
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * On disk structure for xattr block.
|
|
|
|
+ */
|
|
|
|
+struct ocfs2_xattr_block {
|
|
|
|
+/*00*/ __u8 xb_signature[8]; /* Signature for verification */
|
|
|
|
+ __le16 xb_suballoc_slot; /* Slot suballocator this
|
|
|
|
+ block belongs to. */
|
|
|
|
+ __le16 xb_suballoc_bit; /* Bit offset in suballocator
|
|
|
|
+ block group */
|
|
|
|
+ __le32 xb_fs_generation; /* Must match super block */
|
|
|
|
+/*10*/ __le64 xb_blkno; /* Offset on disk, in blocks */
|
|
|
|
+ __le64 xb_csum;
|
|
|
|
+/*20*/ __le16 xb_flags; /* Indicates whether this block contains
|
|
|
|
+ real xattr or a xattr tree. */
|
|
|
|
+ __le16 xb_reserved0;
|
|
|
|
+ __le32 xb_reserved1;
|
|
|
|
+ __le64 xb_reserved2;
|
|
|
|
+/*30*/ union {
|
|
|
|
+ struct ocfs2_xattr_header xb_header; /* xattr header if this
|
|
|
|
+ block contains xattr */
|
|
|
|
+ struct ocfs2_xattr_tree_root xb_root;/* xattr tree root if this
|
|
|
|
+ block cotains xattr
|
|
|
|
+ tree. */
|
|
|
|
+ } xb_attrs;
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+#define OCFS2_XATTR_ENTRY_LOCAL 0x80
|
|
|
|
+#define OCFS2_XATTR_TYPE_MASK 0x7F
|
|
|
|
+static inline void ocfs2_xattr_set_local(struct ocfs2_xattr_entry *xe,
|
|
|
|
+ int local)
|
|
|
|
+{
|
|
|
|
+ if (local)
|
|
|
|
+ xe->xe_type |= OCFS2_XATTR_ENTRY_LOCAL;
|
|
|
|
+ else
|
|
|
|
+ xe->xe_type &= ~OCFS2_XATTR_ENTRY_LOCAL;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static inline int ocfs2_xattr_is_local(struct ocfs2_xattr_entry *xe)
|
|
|
|
+{
|
|
|
|
+ return xe->xe_type & OCFS2_XATTR_ENTRY_LOCAL;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static inline void ocfs2_xattr_set_type(struct ocfs2_xattr_entry *xe, int type)
|
|
|
|
+{
|
|
|
|
+ xe->xe_type |= type & OCFS2_XATTR_TYPE_MASK;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static inline int ocfs2_xattr_get_type(struct ocfs2_xattr_entry *xe)
|
|
|
|
+{
|
|
|
|
+ return xe->xe_type & OCFS2_XATTR_TYPE_MASK;
|
|
|
|
+}
|
|
|
|
+
|
|
#ifdef __KERNEL__
|
|
#ifdef __KERNEL__
|
|
static inline int ocfs2_fast_symlink_chars(struct super_block *sb)
|
|
static inline int ocfs2_fast_symlink_chars(struct super_block *sb)
|
|
{
|
|
{
|