aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTiger Yang <tiger.yang@oracle.com>2008-08-18 05:08:55 -0400
committerMark Fasheh <mfasheh@suse.com>2008-10-13 19:57:02 -0400
commitfdd77704a8b4666a32120fcd1e4a9fedaf3263d8 (patch)
treebfc7ba78487c5c6287354b2b07ee4042bff566bc
parentf56654c435c06f2b2bd5751889b1a08a3add7d6c (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.c22
-rw-r--r--fs/ocfs2/ocfs2.h1
-rw-r--r--fs/ocfs2/ocfs2_fs.h46
-rw-r--r--fs/ocfs2/super.c2
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
6580static void ocfs2_zero_dinode_id2(struct inode *inode, struct ocfs2_dinode *di) 6580static 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
6587void ocfs2_dinode_new_extent_list(struct inode *inode, 6595void 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
6596void ocfs2_set_inode_data_inline(struct inode *inode, struct ocfs2_dinode *di) 6605void 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
6615int ocfs2_convert_inline_data_to_extents(struct inode *inode, 6625int 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
303struct ocfs2_system_inode_info { 309struct 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
857static 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
849static inline int ocfs2_extent_recs_per_inode(struct super_block *sb) 871static 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
881static 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
859static inline int ocfs2_chain_recs_per_inode(struct super_block *sb) 899static 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);