diff options
author | Tiger Yang <tiger.yang@oracle.com> | 2008-08-18 05:08:55 -0400 |
---|---|---|
committer | Mark Fasheh <mfasheh@suse.com> | 2008-10-13 19:57:02 -0400 |
commit | fdd77704a8b4666a32120fcd1e4a9fedaf3263d8 (patch) | |
tree | bfc7ba78487c5c6287354b2b07ee4042bff566bc | |
parent | f56654c435c06f2b2bd5751889b1a08a3add7d6c (diff) |
ocfs2: reserve inline space for extended attribute
Add the structures and helper functions we want for handling inline extended
attributes. We also update the inline-data handlers so that they properly
function in the event that we have both inline data and inline attributes
sharing an inode block.
Signed-off-by: Tiger Yang <tiger.yang@oracle.com>
Signed-off-by: Mark Fasheh <mfasheh@suse.com>
-rw-r--r-- | fs/ocfs2/alloc.c | 22 | ||||
-rw-r--r-- | fs/ocfs2/ocfs2.h | 1 | ||||
-rw-r--r-- | fs/ocfs2/ocfs2_fs.h | 46 | ||||
-rw-r--r-- | fs/ocfs2/super.c | 2 |
4 files changed, 62 insertions, 9 deletions
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index e45421fee204..ace27d1ca574 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c | |||
@@ -6577,20 +6577,29 @@ out: | |||
6577 | return ret; | 6577 | return ret; |
6578 | } | 6578 | } |
6579 | 6579 | ||
6580 | static void ocfs2_zero_dinode_id2(struct inode *inode, struct ocfs2_dinode *di) | 6580 | static void ocfs2_zero_dinode_id2_with_xattr(struct inode *inode, |
6581 | struct ocfs2_dinode *di) | ||
6581 | { | 6582 | { |
6582 | unsigned int blocksize = 1 << inode->i_sb->s_blocksize_bits; | 6583 | unsigned int blocksize = 1 << inode->i_sb->s_blocksize_bits; |
6584 | unsigned int xattrsize = le16_to_cpu(di->i_xattr_inline_size); | ||
6583 | 6585 | ||
6584 | memset(&di->id2, 0, blocksize - offsetof(struct ocfs2_dinode, id2)); | 6586 | if (le16_to_cpu(di->i_dyn_features) & OCFS2_INLINE_XATTR_FL) |
6587 | memset(&di->id2, 0, blocksize - | ||
6588 | offsetof(struct ocfs2_dinode, id2) - | ||
6589 | xattrsize); | ||
6590 | else | ||
6591 | memset(&di->id2, 0, blocksize - | ||
6592 | offsetof(struct ocfs2_dinode, id2)); | ||
6585 | } | 6593 | } |
6586 | 6594 | ||
6587 | void ocfs2_dinode_new_extent_list(struct inode *inode, | 6595 | void ocfs2_dinode_new_extent_list(struct inode *inode, |
6588 | struct ocfs2_dinode *di) | 6596 | struct ocfs2_dinode *di) |
6589 | { | 6597 | { |
6590 | ocfs2_zero_dinode_id2(inode, di); | 6598 | ocfs2_zero_dinode_id2_with_xattr(inode, di); |
6591 | di->id2.i_list.l_tree_depth = 0; | 6599 | di->id2.i_list.l_tree_depth = 0; |
6592 | di->id2.i_list.l_next_free_rec = 0; | 6600 | di->id2.i_list.l_next_free_rec = 0; |
6593 | di->id2.i_list.l_count = cpu_to_le16(ocfs2_extent_recs_per_inode(inode->i_sb)); | 6601 | di->id2.i_list.l_count = cpu_to_le16( |
6602 | ocfs2_extent_recs_per_inode_with_xattr(inode->i_sb, di)); | ||
6594 | } | 6603 | } |
6595 | 6604 | ||
6596 | void ocfs2_set_inode_data_inline(struct inode *inode, struct ocfs2_dinode *di) | 6605 | void ocfs2_set_inode_data_inline(struct inode *inode, struct ocfs2_dinode *di) |
@@ -6607,9 +6616,10 @@ void ocfs2_set_inode_data_inline(struct inode *inode, struct ocfs2_dinode *di) | |||
6607 | * We clear the entire i_data structure here so that all | 6616 | * We clear the entire i_data structure here so that all |
6608 | * fields can be properly initialized. | 6617 | * fields can be properly initialized. |
6609 | */ | 6618 | */ |
6610 | ocfs2_zero_dinode_id2(inode, di); | 6619 | ocfs2_zero_dinode_id2_with_xattr(inode, di); |
6611 | 6620 | ||
6612 | idata->id_count = cpu_to_le16(ocfs2_max_inline_data(inode->i_sb)); | 6621 | idata->id_count = cpu_to_le16( |
6622 | ocfs2_max_inline_data_with_xattr(inode->i_sb, di)); | ||
6613 | } | 6623 | } |
6614 | 6624 | ||
6615 | int ocfs2_convert_inline_data_to_extents(struct inode *inode, | 6625 | int ocfs2_convert_inline_data_to_extents(struct inode *inode, |
diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h index 128279986d65..ce75ca312a2d 100644 --- a/fs/ocfs2/ocfs2.h +++ b/fs/ocfs2/ocfs2.h | |||
@@ -245,6 +245,7 @@ struct ocfs2_super | |||
245 | int s_sectsize_bits; | 245 | int s_sectsize_bits; |
246 | int s_clustersize; | 246 | int s_clustersize; |
247 | int s_clustersize_bits; | 247 | int s_clustersize_bits; |
248 | unsigned int s_xattr_inline_size; | ||
248 | 249 | ||
249 | atomic_t vol_state; | 250 | atomic_t vol_state; |
250 | struct mutex recovery_lock; | 251 | struct mutex recovery_lock; |
diff --git a/fs/ocfs2/ocfs2_fs.h b/fs/ocfs2/ocfs2_fs.h index 1b46505e1e36..1055ba0af9bb 100644 --- a/fs/ocfs2/ocfs2_fs.h +++ b/fs/ocfs2/ocfs2_fs.h | |||
@@ -300,6 +300,12 @@ struct ocfs2_new_group_input { | |||
300 | */ | 300 | */ |
301 | #define OCFS2_DEFAULT_LOCAL_ALLOC_SIZE 8 | 301 | #define OCFS2_DEFAULT_LOCAL_ALLOC_SIZE 8 |
302 | 302 | ||
303 | /* | ||
304 | * Inline extended attribute size (in bytes) | ||
305 | * The value chosen should be aligned to 16 byte boundaries. | ||
306 | */ | ||
307 | #define OCFS2_MIN_XATTR_INLINE_SIZE 256 | ||
308 | |||
303 | struct ocfs2_system_inode_info { | 309 | struct ocfs2_system_inode_info { |
304 | char *si_name; | 310 | char *si_name; |
305 | int si_iflags; | 311 | int si_iflags; |
@@ -622,7 +628,8 @@ struct ocfs2_dinode { | |||
622 | belongs to */ | 628 | belongs to */ |
623 | __le16 i_suballoc_bit; /* Bit offset in suballocator | 629 | __le16 i_suballoc_bit; /* Bit offset in suballocator |
624 | block group */ | 630 | block group */ |
625 | /*10*/ __le32 i_reserved0; | 631 | /*10*/ __le16 i_reserved0; |
632 | __le16 i_xattr_inline_size; | ||
626 | __le32 i_clusters; /* Cluster count */ | 633 | __le32 i_clusters; /* Cluster count */ |
627 | __le32 i_uid; /* Owner UID */ | 634 | __le32 i_uid; /* Owner UID */ |
628 | __le32 i_gid; /* Owning GID */ | 635 | __le32 i_gid; /* Owning GID */ |
@@ -641,11 +648,12 @@ struct ocfs2_dinode { | |||
641 | __le32 i_atime_nsec; | 648 | __le32 i_atime_nsec; |
642 | __le32 i_ctime_nsec; | 649 | __le32 i_ctime_nsec; |
643 | __le32 i_mtime_nsec; | 650 | __le32 i_mtime_nsec; |
644 | __le32 i_attr; | 651 | /*70*/ __le32 i_attr; |
645 | __le16 i_orphaned_slot; /* Only valid when OCFS2_ORPHANED_FL | 652 | __le16 i_orphaned_slot; /* Only valid when OCFS2_ORPHANED_FL |
646 | was set in i_flags */ | 653 | was set in i_flags */ |
647 | __le16 i_dyn_features; | 654 | __le16 i_dyn_features; |
648 | /*70*/ __le64 i_reserved2[8]; | 655 | __le64 i_xattr_loc; |
656 | /*80*/ __le64 i_reserved2[7]; | ||
649 | /*B8*/ union { | 657 | /*B8*/ union { |
650 | __le64 i_pad1; /* Generic way to refer to this | 658 | __le64 i_pad1; /* Generic way to refer to this |
651 | 64bit union */ | 659 | 64bit union */ |
@@ -846,6 +854,20 @@ static inline int ocfs2_max_inline_data(struct super_block *sb) | |||
846 | offsetof(struct ocfs2_dinode, id2.i_data.id_data); | 854 | offsetof(struct ocfs2_dinode, id2.i_data.id_data); |
847 | } | 855 | } |
848 | 856 | ||
857 | static inline int ocfs2_max_inline_data_with_xattr(struct super_block *sb, | ||
858 | struct ocfs2_dinode *di) | ||
859 | { | ||
860 | unsigned int xattrsize = le16_to_cpu(di->i_xattr_inline_size); | ||
861 | |||
862 | if (le16_to_cpu(di->i_dyn_features) & OCFS2_INLINE_XATTR_FL) | ||
863 | return sb->s_blocksize - | ||
864 | offsetof(struct ocfs2_dinode, id2.i_data.id_data) - | ||
865 | xattrsize; | ||
866 | else | ||
867 | return sb->s_blocksize - | ||
868 | offsetof(struct ocfs2_dinode, id2.i_data.id_data); | ||
869 | } | ||
870 | |||
849 | static inline int ocfs2_extent_recs_per_inode(struct super_block *sb) | 871 | static inline int ocfs2_extent_recs_per_inode(struct super_block *sb) |
850 | { | 872 | { |
851 | int size; | 873 | int size; |
@@ -856,6 +878,24 @@ static inline int ocfs2_extent_recs_per_inode(struct super_block *sb) | |||
856 | return size / sizeof(struct ocfs2_extent_rec); | 878 | return size / sizeof(struct ocfs2_extent_rec); |
857 | } | 879 | } |
858 | 880 | ||
881 | static inline int ocfs2_extent_recs_per_inode_with_xattr( | ||
882 | struct super_block *sb, | ||
883 | struct ocfs2_dinode *di) | ||
884 | { | ||
885 | int size; | ||
886 | unsigned int xattrsize = le16_to_cpu(di->i_xattr_inline_size); | ||
887 | |||
888 | if (le16_to_cpu(di->i_dyn_features) & OCFS2_INLINE_XATTR_FL) | ||
889 | size = sb->s_blocksize - | ||
890 | offsetof(struct ocfs2_dinode, id2.i_list.l_recs) - | ||
891 | xattrsize; | ||
892 | else | ||
893 | size = sb->s_blocksize - | ||
894 | offsetof(struct ocfs2_dinode, id2.i_list.l_recs); | ||
895 | |||
896 | return size / sizeof(struct ocfs2_extent_rec); | ||
897 | } | ||
898 | |||
859 | static inline int ocfs2_chain_recs_per_inode(struct super_block *sb) | 899 | static inline int ocfs2_chain_recs_per_inode(struct super_block *sb) |
860 | { | 900 | { |
861 | int size; | 901 | int size; |
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index a2d3dcf70252..9bdb3aeefe89 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c | |||
@@ -1424,6 +1424,8 @@ static int ocfs2_initialize_super(struct super_block *sb, | |||
1424 | 1424 | ||
1425 | osb->slot_num = OCFS2_INVALID_SLOT; | 1425 | osb->slot_num = OCFS2_INVALID_SLOT; |
1426 | 1426 | ||
1427 | osb->s_xattr_inline_size = OCFS2_MIN_XATTR_INLINE_SIZE; | ||
1428 | |||
1427 | osb->local_alloc_state = OCFS2_LA_UNUSED; | 1429 | osb->local_alloc_state = OCFS2_LA_UNUSED; |
1428 | osb->local_alloc_bh = NULL; | 1430 | osb->local_alloc_bh = NULL; |
1429 | INIT_DELAYED_WORK(&osb->la_enable_wq, ocfs2_la_enable_worker); | 1431 | INIT_DELAYED_WORK(&osb->la_enable_wq, ocfs2_la_enable_worker); |