aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTao Ma <tao.ma@oracle.com>2008-08-18 05:38:46 -0400
committerMark Fasheh <mfasheh@suse.com>2008-10-13 16:57:59 -0400
commit5a7bc8eb29b8c759df374d97b6189e03d4ea71c5 (patch)
tree9356d290dccd0afbb1b0e1f183c49bda843df052
parent0eb8d47e69a2211a36643b180f1843ef45f6017d (diff)
ocfs2: Add the basic xattr disk layout in ocfs2_fs.h
Ocfs2 uses a very flexible structure for storing extended attributes on disk. Small amount of attributes are stored directly in the inode block - up to 256 bytes worth. If that fills up, attributes are also stored in an external block, linked to from the inode block. That block can in turn expand to a btree, capable of storing large numbers of attributes. Individual attribute values are stored inline if they're small enough (currently about 80 bytes, this can be changed though), and otherwise are expanded to a btree. The theoretical limit to the size of an individual attribute is about the same as an inode, though the kernel's upper bound on the size of an attributes data is far smaller. Signed-off-by: Tao Ma <tao.ma@oracle.com> Signed-off-by: Mark Fasheh <mfasheh@suse.com>
-rw-r--r--fs/ocfs2/ocfs2_fs.h118
1 files changed, 118 insertions, 0 deletions
diff --git a/fs/ocfs2/ocfs2_fs.h b/fs/ocfs2/ocfs2_fs.h
index 4f619850ccf7..1b46505e1e36 100644
--- a/fs/ocfs2/ocfs2_fs.h
+++ b/fs/ocfs2/ocfs2_fs.h
@@ -64,6 +64,7 @@
64#define OCFS2_INODE_SIGNATURE "INODE01" 64#define OCFS2_INODE_SIGNATURE "INODE01"
65#define OCFS2_EXTENT_BLOCK_SIGNATURE "EXBLK01" 65#define OCFS2_EXTENT_BLOCK_SIGNATURE "EXBLK01"
66#define OCFS2_GROUP_DESC_SIGNATURE "GROUP01" 66#define OCFS2_GROUP_DESC_SIGNATURE "GROUP01"
67#define OCFS2_XATTR_BLOCK_SIGNATURE "XATTR01"
67 68
68/* Compatibility flags */ 69/* Compatibility flags */
69#define OCFS2_HAS_COMPAT_FEATURE(sb,mask) \ 70#define OCFS2_HAS_COMPAT_FEATURE(sb,mask) \
@@ -715,6 +716,123 @@ struct ocfs2_group_desc
715/*40*/ __u8 bg_bitmap[0]; 716/*40*/ __u8 bg_bitmap[0];
716}; 717};
717 718
719/*
720 * On disk extended attribute structure for OCFS2.
721 */
722
723/*
724 * ocfs2_xattr_entry indicates one extend attribute.
725 *
726 * Note that it can be stored in inode, one block or one xattr bucket.
727 */
728struct ocfs2_xattr_entry {
729 __le32 xe_name_hash; /* hash value of xattr prefix+suffix. */
730 __le16 xe_name_offset; /* byte offset from the 1st etnry in the local
731 local xattr storage(inode, xattr block or
732 xattr bucket). */
733 __u8 xe_name_len; /* xattr name len, does't include prefix. */
734 __u8 xe_type; /* the low 7 bits indicates the name prefix's
735 * type and the highest 1 bits indicate whether
736 * the EA is stored in the local storage. */
737 __le64 xe_value_size; /* real xattr value length. */
738};
739
740/*
741 * On disk structure for xattr header.
742 *
743 * One ocfs2_xattr_header describes how many ocfs2_xattr_entry records in
744 * the local xattr storage.
745 */
746struct ocfs2_xattr_header {
747 __le16 xh_count; /* contains the count of how
748 many records are in the
749 local xattr storage. */
750 __le16 xh_reserved1;
751 __le32 xh_reserved2;
752 __le64 xh_csum;
753 struct ocfs2_xattr_entry xh_entries[0]; /* xattr entry list. */
754};
755
756/*
757 * On disk structure for xattr value root.
758 *
759 * It is used when one extended attribute's size is larger, and we will save it
760 * in an outside cluster. It will stored in a b-tree like file content.
761 */
762struct ocfs2_xattr_value_root {
763/*00*/ __le32 xr_clusters; /* clusters covered by xattr value. */
764 __le32 xr_reserved0;
765 __le64 xr_last_eb_blk; /* Pointer to last extent block */
766/*10*/ struct ocfs2_extent_list xr_list; /* Extent record list */
767};
768
769/*
770 * On disk structure for xattr tree root.
771 *
772 * It is used when there are too many extended attributes for one file. These
773 * attributes will be organized and stored in an indexed-btree.
774 */
775struct ocfs2_xattr_tree_root {
776/*00*/ __le32 xt_clusters; /* clusters covered by xattr. */
777 __le32 xt_reserved0;
778 __le64 xt_last_eb_blk; /* Pointer to last extent block */
779/*10*/ struct ocfs2_extent_list xt_list; /* Extent record list */
780};
781
782#define OCFS2_XATTR_INDEXED 0x1
783
784/*
785 * On disk structure for xattr block.
786 */
787struct ocfs2_xattr_block {
788/*00*/ __u8 xb_signature[8]; /* Signature for verification */
789 __le16 xb_suballoc_slot; /* Slot suballocator this
790 block belongs to. */
791 __le16 xb_suballoc_bit; /* Bit offset in suballocator
792 block group */
793 __le32 xb_fs_generation; /* Must match super block */
794/*10*/ __le64 xb_blkno; /* Offset on disk, in blocks */
795 __le64 xb_csum;
796/*20*/ __le16 xb_flags; /* Indicates whether this block contains
797 real xattr or a xattr tree. */
798 __le16 xb_reserved0;
799 __le32 xb_reserved1;
800 __le64 xb_reserved2;
801/*30*/ union {
802 struct ocfs2_xattr_header xb_header; /* xattr header if this
803 block contains xattr */
804 struct ocfs2_xattr_tree_root xb_root;/* xattr tree root if this
805 block cotains xattr
806 tree. */
807 } xb_attrs;
808};
809
810#define OCFS2_XATTR_ENTRY_LOCAL 0x80
811#define OCFS2_XATTR_TYPE_MASK 0x7F
812static inline void ocfs2_xattr_set_local(struct ocfs2_xattr_entry *xe,
813 int local)
814{
815 if (local)
816 xe->xe_type |= OCFS2_XATTR_ENTRY_LOCAL;
817 else
818 xe->xe_type &= ~OCFS2_XATTR_ENTRY_LOCAL;
819}
820
821static inline int ocfs2_xattr_is_local(struct ocfs2_xattr_entry *xe)
822{
823 return xe->xe_type & OCFS2_XATTR_ENTRY_LOCAL;
824}
825
826static inline void ocfs2_xattr_set_type(struct ocfs2_xattr_entry *xe, int type)
827{
828 xe->xe_type |= type & OCFS2_XATTR_TYPE_MASK;
829}
830
831static inline int ocfs2_xattr_get_type(struct ocfs2_xattr_entry *xe)
832{
833 return xe->xe_type & OCFS2_XATTR_TYPE_MASK;
834}
835
718#ifdef __KERNEL__ 836#ifdef __KERNEL__
719static inline int ocfs2_fast_symlink_chars(struct super_block *sb) 837static inline int ocfs2_fast_symlink_chars(struct super_block *sb)
720{ 838{