};
 
 static struct feature feature_list[] = {
-       {BCH_FEATURE_INCOMPAT, BCH_FEATURE_INCOMPAT_LARGE_BUCKET,
+       {BCH_FEATURE_INCOMPAT, BCH_FEATURE_INCOMPAT_LOG_LARGE_BUCKET_SIZE,
                "large_bucket"},
        {0, 0, 0 },
 };
 
 
 /* Feature set definition */
 /* Incompat feature set */
-#define BCH_FEATURE_INCOMPAT_LARGE_BUCKET      0x0001 /* 32bit bucket size */
+/* 32bit bucket size, obsoleted */
+#define BCH_FEATURE_INCOMPAT_OBSO_LARGE_BUCKET         0x0001
+/* real bucket size is (1 << bucket_size) */
+#define BCH_FEATURE_INCOMPAT_LOG_LARGE_BUCKET_SIZE     0x0002
 
 #define BCH_FEATURE_COMPAT_SUPP                0
 #define BCH_FEATURE_RO_COMPAT_SUPP     0
-#define BCH_FEATURE_INCOMPAT_SUPP      BCH_FEATURE_INCOMPAT_LARGE_BUCKET
+#define BCH_FEATURE_INCOMPAT_SUPP      (BCH_FEATURE_INCOMPAT_OBSO_LARGE_BUCKET| \
+                                        BCH_FEATURE_INCOMPAT_LOG_LARGE_BUCKET_SIZE)
 
 #define BCH_HAS_COMPAT_FEATURE(sb, mask) \
                ((sb)->feature_compat & (mask))
                ~BCH##_FEATURE_INCOMPAT_##flagname; \
 }
 
-BCH_FEATURE_INCOMPAT_FUNCS(large_bucket, LARGE_BUCKET);
+BCH_FEATURE_INCOMPAT_FUNCS(obso_large_bucket, OBSO_LARGE_BUCKET);
+BCH_FEATURE_INCOMPAT_FUNCS(large_bucket, LOG_LARGE_BUCKET_SIZE);
 
 static inline bool bch_has_unknown_compat_features(struct cache_sb *sb)
 {
 
 {
        unsigned int bucket_size = le16_to_cpu(s->bucket_size);
 
-       if (sb->version >= BCACHE_SB_VERSION_CDEV_WITH_FEATURES &&
-            bch_has_feature_large_bucket(sb))
-               bucket_size |= le16_to_cpu(s->bucket_size_hi) << 16;
+       if (sb->version >= BCACHE_SB_VERSION_CDEV_WITH_FEATURES) {
+               if (bch_has_feature_large_bucket(sb)) {
+                       unsigned int max, order;
+
+                       max = sizeof(unsigned int) * BITS_PER_BYTE - 1;
+                       order = le16_to_cpu(s->bucket_size);
+                       /*
+                        * bcache tool will make sure the overflow won't
+                        * happen, an error message here is enough.
+                        */
+                       if (order > max)
+                               pr_err("Bucket size (1 << %u) overflows\n",
+                                       order);
+                       bucket_size = 1 << order;
+               } else if (bch_has_feature_obso_large_bucket(sb)) {
+                       bucket_size +=
+                               le16_to_cpu(s->obso_bucket_size_hi) << 16;
+               }
+       }
 
        return bucket_size;
 }