diff options
Diffstat (limited to 'fs/ocfs2/ocfs2_fs.h')
-rw-r--r-- | fs/ocfs2/ocfs2_fs.h | 220 |
1 files changed, 210 insertions, 10 deletions
diff --git a/fs/ocfs2/ocfs2_fs.h b/fs/ocfs2/ocfs2_fs.h index 4f619850ccf7..f24ce3d3f956 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) \ |
@@ -90,7 +91,8 @@ | |||
90 | | OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC \ | 91 | | OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC \ |
91 | | OCFS2_FEATURE_INCOMPAT_INLINE_DATA \ | 92 | | OCFS2_FEATURE_INCOMPAT_INLINE_DATA \ |
92 | | OCFS2_FEATURE_INCOMPAT_EXTENDED_SLOT_MAP \ | 93 | | OCFS2_FEATURE_INCOMPAT_EXTENDED_SLOT_MAP \ |
93 | | OCFS2_FEATURE_INCOMPAT_USERSPACE_STACK) | 94 | | OCFS2_FEATURE_INCOMPAT_USERSPACE_STACK \ |
95 | | OCFS2_FEATURE_INCOMPAT_XATTR) | ||
94 | #define OCFS2_FEATURE_RO_COMPAT_SUPP OCFS2_FEATURE_RO_COMPAT_UNWRITTEN | 96 | #define OCFS2_FEATURE_RO_COMPAT_SUPP OCFS2_FEATURE_RO_COMPAT_UNWRITTEN |
95 | 97 | ||
96 | /* | 98 | /* |
@@ -127,10 +129,6 @@ | |||
127 | /* Support for data packed into inode blocks */ | 129 | /* Support for data packed into inode blocks */ |
128 | #define OCFS2_FEATURE_INCOMPAT_INLINE_DATA 0x0040 | 130 | #define OCFS2_FEATURE_INCOMPAT_INLINE_DATA 0x0040 |
129 | 131 | ||
130 | /* Support for the extended slot map */ | ||
131 | #define OCFS2_FEATURE_INCOMPAT_EXTENDED_SLOT_MAP 0x100 | ||
132 | |||
133 | |||
134 | /* | 132 | /* |
135 | * Support for alternate, userspace cluster stacks. If set, the superblock | 133 | * Support for alternate, userspace cluster stacks. If set, the superblock |
136 | * field s_cluster_info contains a tag for the alternate stack in use as | 134 | * field s_cluster_info contains a tag for the alternate stack in use as |
@@ -142,6 +140,12 @@ | |||
142 | */ | 140 | */ |
143 | #define OCFS2_FEATURE_INCOMPAT_USERSPACE_STACK 0x0080 | 141 | #define OCFS2_FEATURE_INCOMPAT_USERSPACE_STACK 0x0080 |
144 | 142 | ||
143 | /* Support for the extended slot map */ | ||
144 | #define OCFS2_FEATURE_INCOMPAT_EXTENDED_SLOT_MAP 0x100 | ||
145 | |||
146 | /* Support for extended attributes */ | ||
147 | #define OCFS2_FEATURE_INCOMPAT_XATTR 0x0200 | ||
148 | |||
145 | /* | 149 | /* |
146 | * backup superblock flag is used to indicate that this volume | 150 | * backup superblock flag is used to indicate that this volume |
147 | * has backup superblocks. | 151 | * has backup superblocks. |
@@ -299,6 +303,12 @@ struct ocfs2_new_group_input { | |||
299 | */ | 303 | */ |
300 | #define OCFS2_DEFAULT_LOCAL_ALLOC_SIZE 8 | 304 | #define OCFS2_DEFAULT_LOCAL_ALLOC_SIZE 8 |
301 | 305 | ||
306 | /* | ||
307 | * Inline extended attribute size (in bytes) | ||
308 | * The value chosen should be aligned to 16 byte boundaries. | ||
309 | */ | ||
310 | #define OCFS2_MIN_XATTR_INLINE_SIZE 256 | ||
311 | |||
302 | struct ocfs2_system_inode_info { | 312 | struct ocfs2_system_inode_info { |
303 | char *si_name; | 313 | char *si_name; |
304 | int si_iflags; | 314 | int si_iflags; |
@@ -563,7 +573,7 @@ struct ocfs2_super_block { | |||
563 | /*40*/ __le16 s_max_slots; /* Max number of simultaneous mounts | 573 | /*40*/ __le16 s_max_slots; /* Max number of simultaneous mounts |
564 | before tunefs required */ | 574 | before tunefs required */ |
565 | __le16 s_tunefs_flag; | 575 | __le16 s_tunefs_flag; |
566 | __le32 s_reserved1; | 576 | __le32 s_uuid_hash; /* hash value of uuid */ |
567 | __le64 s_first_cluster_group; /* Block offset of 1st cluster | 577 | __le64 s_first_cluster_group; /* Block offset of 1st cluster |
568 | * group header */ | 578 | * group header */ |
569 | /*50*/ __u8 s_label[OCFS2_MAX_VOL_LABEL_LEN]; /* Label for mounting, etc. */ | 579 | /*50*/ __u8 s_label[OCFS2_MAX_VOL_LABEL_LEN]; /* Label for mounting, etc. */ |
@@ -571,7 +581,11 @@ struct ocfs2_super_block { | |||
571 | /*A0*/ struct ocfs2_cluster_info s_cluster_info; /* Selected userspace | 581 | /*A0*/ struct ocfs2_cluster_info s_cluster_info; /* Selected userspace |
572 | stack. Only valid | 582 | stack. Only valid |
573 | with INCOMPAT flag. */ | 583 | with INCOMPAT flag. */ |
574 | /*B8*/ __le64 s_reserved2[17]; /* Fill out superblock */ | 584 | /*B8*/ __le16 s_xattr_inline_size; /* extended attribute inline size |
585 | for this fs*/ | ||
586 | __le16 s_reserved0; | ||
587 | __le32 s_reserved1; | ||
588 | /*C0*/ __le64 s_reserved2[16]; /* Fill out superblock */ | ||
575 | /*140*/ | 589 | /*140*/ |
576 | 590 | ||
577 | /* | 591 | /* |
@@ -621,7 +635,8 @@ struct ocfs2_dinode { | |||
621 | belongs to */ | 635 | belongs to */ |
622 | __le16 i_suballoc_bit; /* Bit offset in suballocator | 636 | __le16 i_suballoc_bit; /* Bit offset in suballocator |
623 | block group */ | 637 | block group */ |
624 | /*10*/ __le32 i_reserved0; | 638 | /*10*/ __le16 i_reserved0; |
639 | __le16 i_xattr_inline_size; | ||
625 | __le32 i_clusters; /* Cluster count */ | 640 | __le32 i_clusters; /* Cluster count */ |
626 | __le32 i_uid; /* Owner UID */ | 641 | __le32 i_uid; /* Owner UID */ |
627 | __le32 i_gid; /* Owning GID */ | 642 | __le32 i_gid; /* Owning GID */ |
@@ -640,11 +655,12 @@ struct ocfs2_dinode { | |||
640 | __le32 i_atime_nsec; | 655 | __le32 i_atime_nsec; |
641 | __le32 i_ctime_nsec; | 656 | __le32 i_ctime_nsec; |
642 | __le32 i_mtime_nsec; | 657 | __le32 i_mtime_nsec; |
643 | __le32 i_attr; | 658 | /*70*/ __le32 i_attr; |
644 | __le16 i_orphaned_slot; /* Only valid when OCFS2_ORPHANED_FL | 659 | __le16 i_orphaned_slot; /* Only valid when OCFS2_ORPHANED_FL |
645 | was set in i_flags */ | 660 | was set in i_flags */ |
646 | __le16 i_dyn_features; | 661 | __le16 i_dyn_features; |
647 | /*70*/ __le64 i_reserved2[8]; | 662 | __le64 i_xattr_loc; |
663 | /*80*/ __le64 i_reserved2[7]; | ||
648 | /*B8*/ union { | 664 | /*B8*/ union { |
649 | __le64 i_pad1; /* Generic way to refer to this | 665 | __le64 i_pad1; /* Generic way to refer to this |
650 | 64bit union */ | 666 | 64bit union */ |
@@ -715,6 +731,136 @@ struct ocfs2_group_desc | |||
715 | /*40*/ __u8 bg_bitmap[0]; | 731 | /*40*/ __u8 bg_bitmap[0]; |
716 | }; | 732 | }; |
717 | 733 | ||
734 | /* | ||
735 | * On disk extended attribute structure for OCFS2. | ||
736 | */ | ||
737 | |||
738 | /* | ||
739 | * ocfs2_xattr_entry indicates one extend attribute. | ||
740 | * | ||
741 | * Note that it can be stored in inode, one block or one xattr bucket. | ||
742 | */ | ||
743 | struct ocfs2_xattr_entry { | ||
744 | __le32 xe_name_hash; /* hash value of xattr prefix+suffix. */ | ||
745 | __le16 xe_name_offset; /* byte offset from the 1st etnry in the local | ||
746 | local xattr storage(inode, xattr block or | ||
747 | xattr bucket). */ | ||
748 | __u8 xe_name_len; /* xattr name len, does't include prefix. */ | ||
749 | __u8 xe_type; /* the low 7 bits indicates the name prefix's | ||
750 | * type and the highest 1 bits indicate whether | ||
751 | * the EA is stored in the local storage. */ | ||
752 | __le64 xe_value_size; /* real xattr value length. */ | ||
753 | }; | ||
754 | |||
755 | /* | ||
756 | * On disk structure for xattr header. | ||
757 | * | ||
758 | * One ocfs2_xattr_header describes how many ocfs2_xattr_entry records in | ||
759 | * the local xattr storage. | ||
760 | */ | ||
761 | struct ocfs2_xattr_header { | ||
762 | __le16 xh_count; /* contains the count of how | ||
763 | many records are in the | ||
764 | local xattr storage. */ | ||
765 | __le16 xh_free_start; /* current offset for storing | ||
766 | xattr. */ | ||
767 | __le16 xh_name_value_len; /* total length of name/value | ||
768 | length in this bucket. */ | ||
769 | __le16 xh_num_buckets; /* bucket nums in one extent | ||
770 | record, only valid in the | ||
771 | first bucket. */ | ||
772 | __le64 xh_csum; | ||
773 | struct ocfs2_xattr_entry xh_entries[0]; /* xattr entry list. */ | ||
774 | }; | ||
775 | |||
776 | /* | ||
777 | * On disk structure for xattr value root. | ||
778 | * | ||
779 | * It is used when one extended attribute's size is larger, and we will save it | ||
780 | * in an outside cluster. It will stored in a b-tree like file content. | ||
781 | */ | ||
782 | struct ocfs2_xattr_value_root { | ||
783 | /*00*/ __le32 xr_clusters; /* clusters covered by xattr value. */ | ||
784 | __le32 xr_reserved0; | ||
785 | __le64 xr_last_eb_blk; /* Pointer to last extent block */ | ||
786 | /*10*/ struct ocfs2_extent_list xr_list; /* Extent record list */ | ||
787 | }; | ||
788 | |||
789 | /* | ||
790 | * On disk structure for xattr tree root. | ||
791 | * | ||
792 | * It is used when there are too many extended attributes for one file. These | ||
793 | * attributes will be organized and stored in an indexed-btree. | ||
794 | */ | ||
795 | struct ocfs2_xattr_tree_root { | ||
796 | /*00*/ __le32 xt_clusters; /* clusters covered by xattr. */ | ||
797 | __le32 xt_reserved0; | ||
798 | __le64 xt_last_eb_blk; /* Pointer to last extent block */ | ||
799 | /*10*/ struct ocfs2_extent_list xt_list; /* Extent record list */ | ||
800 | }; | ||
801 | |||
802 | #define OCFS2_XATTR_INDEXED 0x1 | ||
803 | #define OCFS2_HASH_SHIFT 5 | ||
804 | #define OCFS2_XATTR_ROUND 3 | ||
805 | #define OCFS2_XATTR_SIZE(size) (((size) + OCFS2_XATTR_ROUND) & \ | ||
806 | ~(OCFS2_XATTR_ROUND)) | ||
807 | |||
808 | #define OCFS2_XATTR_BUCKET_SIZE 4096 | ||
809 | #define OCFS2_XATTR_MAX_BLOCKS_PER_BUCKET (OCFS2_XATTR_BUCKET_SIZE \ | ||
810 | / OCFS2_MIN_BLOCKSIZE) | ||
811 | |||
812 | /* | ||
813 | * On disk structure for xattr block. | ||
814 | */ | ||
815 | struct ocfs2_xattr_block { | ||
816 | /*00*/ __u8 xb_signature[8]; /* Signature for verification */ | ||
817 | __le16 xb_suballoc_slot; /* Slot suballocator this | ||
818 | block belongs to. */ | ||
819 | __le16 xb_suballoc_bit; /* Bit offset in suballocator | ||
820 | block group */ | ||
821 | __le32 xb_fs_generation; /* Must match super block */ | ||
822 | /*10*/ __le64 xb_blkno; /* Offset on disk, in blocks */ | ||
823 | __le64 xb_csum; | ||
824 | /*20*/ __le16 xb_flags; /* Indicates whether this block contains | ||
825 | real xattr or a xattr tree. */ | ||
826 | __le16 xb_reserved0; | ||
827 | __le32 xb_reserved1; | ||
828 | __le64 xb_reserved2; | ||
829 | /*30*/ union { | ||
830 | struct ocfs2_xattr_header xb_header; /* xattr header if this | ||
831 | block contains xattr */ | ||
832 | struct ocfs2_xattr_tree_root xb_root;/* xattr tree root if this | ||
833 | block cotains xattr | ||
834 | tree. */ | ||
835 | } xb_attrs; | ||
836 | }; | ||
837 | |||
838 | #define OCFS2_XATTR_ENTRY_LOCAL 0x80 | ||
839 | #define OCFS2_XATTR_TYPE_MASK 0x7F | ||
840 | static inline void ocfs2_xattr_set_local(struct ocfs2_xattr_entry *xe, | ||
841 | int local) | ||
842 | { | ||
843 | if (local) | ||
844 | xe->xe_type |= OCFS2_XATTR_ENTRY_LOCAL; | ||
845 | else | ||
846 | xe->xe_type &= ~OCFS2_XATTR_ENTRY_LOCAL; | ||
847 | } | ||
848 | |||
849 | static inline int ocfs2_xattr_is_local(struct ocfs2_xattr_entry *xe) | ||
850 | { | ||
851 | return xe->xe_type & OCFS2_XATTR_ENTRY_LOCAL; | ||
852 | } | ||
853 | |||
854 | static inline void ocfs2_xattr_set_type(struct ocfs2_xattr_entry *xe, int type) | ||
855 | { | ||
856 | xe->xe_type |= type & OCFS2_XATTR_TYPE_MASK; | ||
857 | } | ||
858 | |||
859 | static inline int ocfs2_xattr_get_type(struct ocfs2_xattr_entry *xe) | ||
860 | { | ||
861 | return xe->xe_type & OCFS2_XATTR_TYPE_MASK; | ||
862 | } | ||
863 | |||
718 | #ifdef __KERNEL__ | 864 | #ifdef __KERNEL__ |
719 | static inline int ocfs2_fast_symlink_chars(struct super_block *sb) | 865 | static inline int ocfs2_fast_symlink_chars(struct super_block *sb) |
720 | { | 866 | { |
@@ -728,6 +874,20 @@ static inline int ocfs2_max_inline_data(struct super_block *sb) | |||
728 | offsetof(struct ocfs2_dinode, id2.i_data.id_data); | 874 | offsetof(struct ocfs2_dinode, id2.i_data.id_data); |
729 | } | 875 | } |
730 | 876 | ||
877 | static inline int ocfs2_max_inline_data_with_xattr(struct super_block *sb, | ||
878 | struct ocfs2_dinode *di) | ||
879 | { | ||
880 | unsigned int xattrsize = le16_to_cpu(di->i_xattr_inline_size); | ||
881 | |||
882 | if (le16_to_cpu(di->i_dyn_features) & OCFS2_INLINE_XATTR_FL) | ||
883 | return sb->s_blocksize - | ||
884 | offsetof(struct ocfs2_dinode, id2.i_data.id_data) - | ||
885 | xattrsize; | ||
886 | else | ||
887 | return sb->s_blocksize - | ||
888 | offsetof(struct ocfs2_dinode, id2.i_data.id_data); | ||
889 | } | ||
890 | |||
731 | static inline int ocfs2_extent_recs_per_inode(struct super_block *sb) | 891 | static inline int ocfs2_extent_recs_per_inode(struct super_block *sb) |
732 | { | 892 | { |
733 | int size; | 893 | int size; |
@@ -738,6 +898,24 @@ static inline int ocfs2_extent_recs_per_inode(struct super_block *sb) | |||
738 | return size / sizeof(struct ocfs2_extent_rec); | 898 | return size / sizeof(struct ocfs2_extent_rec); |
739 | } | 899 | } |
740 | 900 | ||
901 | static inline int ocfs2_extent_recs_per_inode_with_xattr( | ||
902 | struct super_block *sb, | ||
903 | struct ocfs2_dinode *di) | ||
904 | { | ||
905 | int size; | ||
906 | unsigned int xattrsize = le16_to_cpu(di->i_xattr_inline_size); | ||
907 | |||
908 | if (le16_to_cpu(di->i_dyn_features) & OCFS2_INLINE_XATTR_FL) | ||
909 | size = sb->s_blocksize - | ||
910 | offsetof(struct ocfs2_dinode, id2.i_list.l_recs) - | ||
911 | xattrsize; | ||
912 | else | ||
913 | size = sb->s_blocksize - | ||
914 | offsetof(struct ocfs2_dinode, id2.i_list.l_recs); | ||
915 | |||
916 | return size / sizeof(struct ocfs2_extent_rec); | ||
917 | } | ||
918 | |||
741 | static inline int ocfs2_chain_recs_per_inode(struct super_block *sb) | 919 | static inline int ocfs2_chain_recs_per_inode(struct super_block *sb) |
742 | { | 920 | { |
743 | int size; | 921 | int size; |
@@ -801,6 +979,17 @@ static inline u64 ocfs2_backup_super_blkno(struct super_block *sb, int index) | |||
801 | return 0; | 979 | return 0; |
802 | 980 | ||
803 | } | 981 | } |
982 | |||
983 | static inline u16 ocfs2_xattr_recs_per_xb(struct super_block *sb) | ||
984 | { | ||
985 | int size; | ||
986 | |||
987 | size = sb->s_blocksize - | ||
988 | offsetof(struct ocfs2_xattr_block, | ||
989 | xb_attrs.xb_root.xt_list.l_recs); | ||
990 | |||
991 | return size / sizeof(struct ocfs2_extent_rec); | ||
992 | } | ||
804 | #else | 993 | #else |
805 | static inline int ocfs2_fast_symlink_chars(int blocksize) | 994 | static inline int ocfs2_fast_symlink_chars(int blocksize) |
806 | { | 995 | { |
@@ -884,6 +1073,17 @@ static inline uint64_t ocfs2_backup_super_blkno(int blocksize, int index) | |||
884 | 1073 | ||
885 | return 0; | 1074 | return 0; |
886 | } | 1075 | } |
1076 | |||
1077 | static inline int ocfs2_xattr_recs_per_xb(int blocksize) | ||
1078 | { | ||
1079 | int size; | ||
1080 | |||
1081 | size = blocksize - | ||
1082 | offsetof(struct ocfs2_xattr_block, | ||
1083 | xb_attrs.xb_root.xt_list.l_recs); | ||
1084 | |||
1085 | return size / sizeof(struct ocfs2_extent_rec); | ||
1086 | } | ||
887 | #endif /* __KERNEL__ */ | 1087 | #endif /* __KERNEL__ */ |
888 | 1088 | ||
889 | 1089 | ||