MIPS: Oprofile: Loongson: Unify macro for setting events
[cascardo/linux.git] / fs / ocfs2 / ocfs2_fs.h
index bb37218..33f1c9a 100644 (file)
                                         | OCFS2_FEATURE_INCOMPAT_XATTR \
                                         | OCFS2_FEATURE_INCOMPAT_META_ECC \
                                         | OCFS2_FEATURE_INCOMPAT_INDEXED_DIRS \
-                                        | OCFS2_FEATURE_INCOMPAT_REFCOUNT_TREE)
+                                        | OCFS2_FEATURE_INCOMPAT_REFCOUNT_TREE \
+                                        | OCFS2_FEATURE_INCOMPAT_DISCONTIG_BG)
 #define OCFS2_FEATURE_RO_COMPAT_SUPP   (OCFS2_FEATURE_RO_COMPAT_UNWRITTEN \
                                         | OCFS2_FEATURE_RO_COMPAT_USRQUOTA \
                                         | OCFS2_FEATURE_RO_COMPAT_GRPQUOTA)
 /* Refcount tree support */
 #define OCFS2_FEATURE_INCOMPAT_REFCOUNT_TREE   0x1000
 
+/* Discontigous block groups */
+#define OCFS2_FEATURE_INCOMPAT_DISCONTIG_BG    0x2000
+
 /*
  * backup superblock flag is used to indicate that this volume
  * has backup superblocks.
 /* Journal limits (in bytes) */
 #define OCFS2_MIN_JOURNAL_SIZE         (4 * 1024 * 1024)
 
-/*
- * Default local alloc size (in megabytes)
- *
- * The value chosen should be such that most allocations, including new
- * block groups, use local alloc.
- */
-#define OCFS2_DEFAULT_LOCAL_ALLOC_SIZE 8
-
 /*
  * Inline extended attribute size (in bytes)
  * The value chosen should be aligned to 16 byte boundaries.
@@ -512,7 +508,10 @@ struct ocfs2_extent_block
                                           block group */
        __le32 h_fs_generation;         /* Must match super block */
        __le64 h_blkno;                 /* Offset on disk, in blocks */
-/*20*/ __le64 h_reserved3;
+/*20*/ __le64 h_suballoc_loc;          /* Suballocator block group this
+                                          eb belongs to.  Only valid
+                                          if allocated from a
+                                          discontiguous block group */
        __le64 h_next_leaf_blk;         /* Offset on disk, in blocks,
                                           of next leaf header pointing
                                           to data */
@@ -679,7 +678,11 @@ struct ocfs2_dinode {
 /*80*/ struct ocfs2_block_check i_check;       /* Error checking */
 /*88*/ __le64 i_dx_root;               /* Pointer to dir index root block */
 /*90*/ __le64 i_refcount_loc;
-       __le64 i_reserved2[4];
+       __le64 i_suballoc_loc;          /* Suballocator block group this
+                                          inode belongs to.  Only valid
+                                          if allocated from a
+                                          discontiguous block group */
+/*A0*/ __le64 i_reserved2[3];
 /*B8*/ union {
                __le64 i_pad1;          /* Generic way to refer to this
                                           64bit union */
@@ -814,7 +817,12 @@ struct ocfs2_dx_root_block {
        __le32          dr_reserved2;
        __le64          dr_free_blk;            /* Pointer to head of free
                                                 * unindexed block list. */
-       __le64          dr_reserved3[15];
+       __le64          dr_suballoc_loc;        /* Suballocator block group
+                                                  this root belongs to.
+                                                  Only valid if allocated
+                                                  from a discontiguous
+                                                  block group */
+       __le64          dr_reserved3[14];
        union {
                struct ocfs2_extent_list dr_list; /* Keep this aligned to 128
                                                   * bits for maximum space
@@ -839,6 +847,13 @@ struct ocfs2_dx_leaf {
        struct ocfs2_dx_entry_list      dl_list;
 };
 
+/*
+ * Largest bitmap for a block (suballocator) group in bytes.  This limit
+ * does not affect cluster groups (global allocator).  Cluster group
+ * bitmaps run to the end of the block.
+ */
+#define OCFS2_MAX_BG_BITMAP_SIZE       256
+
 /*
  * On disk allocator group structure for OCFS2
  */
@@ -860,7 +875,29 @@ struct ocfs2_group_desc
        __le64   bg_blkno;               /* Offset on disk, in blocks */
 /*30*/ struct ocfs2_block_check bg_check;      /* Error checking */
        __le64   bg_reserved2;
-/*40*/ __u8    bg_bitmap[0];
+/*40*/ union {
+               __u8    bg_bitmap[0];
+               struct {
+                       /*
+                        * Block groups may be discontiguous when
+                        * OCFS2_FEATURE_INCOMPAT_DISCONTIG_BG is set.
+                        * The extents of a discontigous block group are
+                        * stored in bg_list.  It is a flat list.
+                        * l_tree_depth must always be zero.  A
+                        * discontiguous group is signified by a non-zero
+                        * bg_list->l_next_free_rec.  Only block groups
+                        * can be discontiguous; Cluster groups cannot.
+                        * We've never made a block group with more than
+                        * 2048 blocks (256 bytes of bg_bitmap).  This
+                        * codifies that limit so that we can fit bg_list.
+                        * bg_size of a discontiguous block group will
+                        * be 256 to match bg_bitmap_filler.
+                        */
+                       __u8 bg_bitmap_filler[OCFS2_MAX_BG_BITMAP_SIZE];
+/*140*/                        struct ocfs2_extent_list bg_list;
+               };
+       };
+/* Actual on-disk size is one block */
 };
 
 struct ocfs2_refcount_rec {
@@ -905,7 +942,11 @@ struct ocfs2_refcount_block {
 /*40*/ __le32 rf_generation;           /* generation number. all be the same
                                         * for the same refcount tree. */
        __le32 rf_reserved0;
-       __le64 rf_reserved1[7];
+       __le64 rf_suballoc_loc;         /* Suballocator block group this
+                                          refcount block belongs to. Only
+                                          valid if allocated from a
+                                          discontiguous block group */
+/*50*/ __le64 rf_reserved1[6];
 /*80*/ union {
                struct ocfs2_refcount_list rf_records;  /* List of refcount
                                                          records */
@@ -1017,7 +1058,10 @@ struct ocfs2_xattr_block {
                                        real xattr or a xattr tree. */
        __le16  xb_reserved0;
        __le32  xb_reserved1;
-       __le64  xb_reserved2;
+       __le64  xb_suballoc_loc;        /* Suballocator block group this
+                                          xattr block belongs to. Only
+                                          valid if allocated from a
+                                          discontiguous block group */
 /*30*/ union {
                struct ocfs2_xattr_header xb_header; /* xattr header if this
                                                        block contains xattr */
@@ -1254,6 +1298,16 @@ static inline u16 ocfs2_extent_recs_per_eb(struct super_block *sb)
        return size / sizeof(struct ocfs2_extent_rec);
 }
 
+static inline u16 ocfs2_extent_recs_per_gd(struct super_block *sb)
+{
+       int size;
+
+       size = sb->s_blocksize -
+               offsetof(struct ocfs2_group_desc, bg_list.l_recs);
+
+       return size / sizeof(struct ocfs2_extent_rec);
+}
+
 static inline int ocfs2_dx_entries_per_leaf(struct super_block *sb)
 {
        int size;
@@ -1284,13 +1338,23 @@ static inline u16 ocfs2_local_alloc_size(struct super_block *sb)
        return size;
 }
 
-static inline int ocfs2_group_bitmap_size(struct super_block *sb)
+static inline int ocfs2_group_bitmap_size(struct super_block *sb,
+                                         int suballocator,
+                                         u32 feature_incompat)
 {
-       int size;
-
-       size = sb->s_blocksize -
+       int size = sb->s_blocksize -
                offsetof(struct ocfs2_group_desc, bg_bitmap);
 
+       /*
+        * The cluster allocator uses the entire block.  Suballocators have
+        * never used more than OCFS2_MAX_BG_BITMAP_SIZE.  Unfortunately, older
+        * code expects bg_size set to the maximum.  Thus we must keep
+        * bg_size as-is unless discontig_bg is enabled.
+        */
+       if (suballocator &&
+           (feature_incompat & OCFS2_FEATURE_INCOMPAT_DISCONTIG_BG))
+               size = OCFS2_MAX_BG_BITMAP_SIZE;
+
        return size;
 }
 
@@ -1402,23 +1466,43 @@ static inline int ocfs2_extent_recs_per_eb(int blocksize)
        return size / sizeof(struct ocfs2_extent_rec);
 }
 
-static inline int ocfs2_local_alloc_size(int blocksize)
+static inline int ocfs2_extent_recs_per_gd(int blocksize)
 {
        int size;
 
        size = blocksize -
-               offsetof(struct ocfs2_dinode, id2.i_lab.la_bitmap);
+               offsetof(struct ocfs2_group_desc, bg_list.l_recs);
 
-       return size;
+       return size / sizeof(struct ocfs2_extent_rec);
 }
 
-static inline int ocfs2_group_bitmap_size(int blocksize)
+static inline int ocfs2_local_alloc_size(int blocksize)
 {
        int size;
 
        size = blocksize -
+               offsetof(struct ocfs2_dinode, id2.i_lab.la_bitmap);
+
+       return size;
+}
+
+static inline int ocfs2_group_bitmap_size(int blocksize,
+                                         int suballocator,
+                                         uint32_t feature_incompat)
+{
+       int size = sb->s_blocksize -
                offsetof(struct ocfs2_group_desc, bg_bitmap);
 
+       /*
+        * The cluster allocator uses the entire block.  Suballocators have
+        * never used more than OCFS2_MAX_BG_BITMAP_SIZE.  Unfortunately, older
+        * code expects bg_size set to the maximum.  Thus we must keep
+        * bg_size as-is unless discontig_bg is enabled.
+        */
+       if (suballocator &&
+           (feature_incompat & OCFS2_FEATURE_INCOMPAT_DISCONTIG_BG))
+               size = OCFS2_MAX_BG_BITMAP_SIZE;
+
        return size;
 }
 
@@ -1491,5 +1575,19 @@ static inline void ocfs2_set_de_type(struct ocfs2_dir_entry *de,
        de->file_type = ocfs2_type_by_mode[(mode & S_IFMT)>>S_SHIFT];
 }
 
+static inline int ocfs2_gd_is_discontig(struct ocfs2_group_desc *gd)
+{
+       if ((offsetof(struct ocfs2_group_desc, bg_bitmap) +
+            le16_to_cpu(gd->bg_size)) !=
+           offsetof(struct ocfs2_group_desc, bg_list))
+               return 0;
+       /*
+        * Only valid to check l_next_free_rec if
+        * bg_bitmap + bg_size == bg_list.
+        */
+       if (!gd->bg_list.l_next_free_rec)
+               return 0;
+       return 1;
+}
 #endif  /* _OCFS2_FS_H */