diff options
-rw-r--r-- | Create.c | 8 | ||||
-rw-r--r-- | mdadm.h | 2 | ||||
-rw-r--r-- | platform-intel.h | 49 | ||||
-rw-r--r-- | super-intel.c | 12 |
4 files changed, 69 insertions, 2 deletions
@@ -235,9 +235,13 @@ int Create(struct supertype *st, char *mddev, case 6: case 0: if (chunk == 0) { - chunk = 512; + if (st && st->ss->default_chunk) + chunk = st->ss->default_chunk(st); + + chunk = chunk ? : 512; + if (verbose > 0) - fprintf(stderr, Name ": chunk size defaults to 512K\n"); + fprintf(stderr, Name ": chunk size defaults to %dK\n", chunk); } break; case LEVEL_LINEAR: @@ -609,6 +609,8 @@ extern struct superswitch { struct mdinfo *(*container_content)(struct supertype *st); /* Allow a metadata handler to override mdadm's default layouts */ int (*default_layout)(int level); /* optional */ + /* query the supertype for default chunk size */ + int (*default_chunk)(struct supertype *st); /* optional */ /* for mdmon */ int (*open_new)(struct supertype *c, struct active_array *a, diff --git a/platform-intel.h b/platform-intel.h index bbdc9f9..9088436 100644 --- a/platform-intel.h +++ b/platform-intel.h @@ -115,6 +115,55 @@ static inline int imsm_orom_has_chunk(const struct imsm_orom *orom, int chunk) return !!(orom->sss & (1 << (fs - 1))); } +/** + * fls - find last (most-significant) bit set + * @x: the word to search + * The funciton is borrowed from Linux kernel code + * include/asm-generic/bitops/fls.h + */ +static inline int fls(int x) +{ + int r = 32; + + if (!x) + return 0; + if (!(x & 0xffff0000u)) { + x <<= 16; + r -= 16; + } + if (!(x & 0xff000000u)) { + x <<= 8; + r -= 8; + } + if (!(x & 0xf0000000u)) { + x <<= 4; + r -= 4; + } + if (!(x & 0xc0000000u)) { + x <<= 2; + r -= 2; + } + if (!(x & 0x80000000u)) { + x <<= 1; + r -= 1; + } + return r; +} + +/** + * imsm_orom_default_chunk - return the largest chunk size supported via orom + * @orom: orom pointer from find_imsm_orom + */ +static inline int imsm_orom_default_chunk(const struct imsm_orom *orom) +{ + int fs = fls(orom->sss); + + if (!fs) + return 0; + + return min(512, (1 << fs)); +} + struct sys_dev { char *path; struct sys_dev *next; diff --git a/super-intel.c b/super-intel.c index 394ace4..e212d9a 100644 --- a/super-intel.c +++ b/super-intel.c @@ -4003,6 +4003,17 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout, close(cfd); return 0; } + +static int default_chunk_imsm(struct supertype *st) +{ + struct intel_super *super = st->sb; + + if (!super->orom) + return 0; + + return imsm_orom_default_chunk(super->orom); +} + #endif /* MDASSEMBLE */ static int is_rebuilding(struct imsm_dev *dev) @@ -5240,6 +5251,7 @@ struct superswitch super_imsm = { .brief_detail_super = brief_detail_super_imsm, .write_init_super = write_init_super_imsm, .validate_geometry = validate_geometry_imsm, + .default_chunk = default_chunk_imsm, .add_to_super = add_to_super_imsm, .detail_platform = detail_platform_imsm, #endif |