diff options
author | Neil Brown <neilb@suse.de> | 2005-08-26 06:08:28 +0000 |
---|---|---|
committer | Neil Brown <neilb@suse.de> | 2005-08-26 06:08:28 +0000 |
commit | 1bf4e2d962d0d7937bb24799aaa636edc6497fa4 (patch) | |
tree | bff99a373d7be1d0d7ccfd9d85998993a39c5cdf /super1.c | |
parent | 8431b2b2861d08b517468ae0f3ce2e3502d5ea94 (diff) | |
download | mdadm-1bf4e2d962d0d7937bb24799aaa636edc6497fa4.tar.gz mdadm-1bf4e2d962d0d7937bb24799aaa636edc6497fa4.tar.xz mdadm-1bf4e2d962d0d7937bb24799aaa636edc6497fa4.zip |
Passes all tests, nearly ready for release.
Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
Diffstat (limited to 'super1.c')
-rw-r--r-- | super1.c | 117 |
1 files changed, 43 insertions, 74 deletions
@@ -526,8 +526,7 @@ static int store_super1(struct supertype *st, int fd, void *sbv) static int load_super1(struct supertype *st, int fd, void **sbp, char *devname); static int write_init_super1(struct supertype *st, void *sbv, - mdu_disk_info_t *dinfo, char *devname, - int reserve) + mdu_disk_info_t *dinfo, char *devname) { struct mdp_superblock_1 *sb = sbv; struct mdp_superblock_1 *refsb = NULL; @@ -595,18 +594,18 @@ static int write_init_super1(struct supertype *st, void *sbv, sb_offset &= ~(4*2-1); sb->super_offset = __cpu_to_le64(sb_offset); sb->data_offset = __cpu_to_le64(0); - sb->data_size = __cpu_to_le64(sb_offset - reserve); + sb->data_size = __cpu_to_le64(sb_offset); break; case 1: sb->super_offset = __cpu_to_le64(0); - sb->data_offset = __cpu_to_le64(2 + reserve); - sb->data_size = __cpu_to_le64(size - 2 - reserve); + sb->data_offset = __cpu_to_le64(4*2); /* leave 4k for super and bitmap */ + sb->data_size = __cpu_to_le64(size - 4*2); break; case 2: sb_offset = 4*2; sb->super_offset = __cpu_to_le64(sb_offset); - sb->data_offset = __cpu_to_le64(sb_offset+2 + reserve); - sb->data_size = __cpu_to_le64(size - 4*2 - 2 - reserve); + sb->data_offset = __cpu_to_le64(sb_offset+4*2); + sb->data_size = __cpu_to_le64(size - 4*2 - 4*2); break; default: return -EINVAL; @@ -618,29 +617,8 @@ static int write_init_super1(struct supertype *st, void *sbv, if (rv) fprintf(stderr, Name ": failed to write superblock to %s\n", devname); - if (__le32_to_cpu(sb->feature_map) & 1) { - /* write the bitmap */ - int towrite, n; - char buf[4096]; - - st->ss->locate_bitmap(st, fd); - write(fd, ((char*)sb)+1024, sizeof(bitmap_super_t)); - towrite = 62*1024; - memset(buf, 0xff, sizeof(buf)); - while (towrite > 0) { - n=towrite; - if (n > sizeof(buf)) - n = sizeof(buf); - n = write(fd, buf, n); - if (n > 0) - towrite -= n; - else - break; - } - if (towrite) - rv = -2; - } - fsync(fd); + if (rv == 0 && (__le32_to_cpu(sb->feature_map) & 1)) + rv = st->ss->write_bitmap(st, fd, sbv); close(fd); return rv; } @@ -835,42 +813,54 @@ static struct supertype *match_metadata_desc1(char *arg) * superblock type st, and reserving 'reserve' sectors for * a possible bitmap */ -static __u64 avail_size1(struct supertype *st, __u64 devsize, int reserve) +static __u64 avail_size1(struct supertype *st, __u64 devsize) { if (devsize < 24) return 0; switch(st->minor_version) { case 0: - /* at end, with reserve before it */ - return ((devsize - 8*2 ) & ~(4*2-1)) - reserve; + /* at end */ + return ((devsize - 8*2 ) & ~(4*2-1)); case 1: - /* at start, 1K for superblock */ - return devsize - 2 - reserve; + /* at start, 4K for superblock and possible bitmap */ + return devsize - 4*2; case 2: - /* 4k from start, 1K for superblock */ - return devsize - (4+1)*2 - reserve; + /* 4k from start, 4K for superblock and possible bitmap */ + return devsize - (4+4)*2; } return 0; } -static int add_internal_bitmap1(struct supertype *st, void *sbv, int chunk, int delay, int write_behind, unsigned long long size) +static int +add_internal_bitmap1(struct supertype *st, void *sbv, + int chunk, int delay, int write_behind, int *sizep, int may_change) { /* - * The bitmap comes immediately before of after the superblock and must be 62K in size - * at most. The default size is between 31K and 62K + * If not may_change, then this is a 'Grow', and the bitmap + * must fit after the superblock. + * If may_change, then this is create, and we can put the bitmap + * before the superblock if we like, or may move the start. + * For now, just squeeze the bitmap into 3k and don't change anything. * * size is in K, chunk is in bytes !!! */ - unsigned long long bits = size; - unsigned long long max_bits = 62*1024*8; + unsigned long long size = *sizep; + unsigned long long bits; + unsigned long long max_bits = (3*512 - sizeof(bitmap_super_t)) * 8; unsigned long long min_chunk; struct mdp_superblock_1 *sb = sbv; bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb) + 1024); + if (st->minor_version && !may_change && + __le64_to_cpu(sb->data_offset) - __le64_to_cpu(sb->super_offset) < 8) + return 0; /* doesn't fit */ + + min_chunk = 4096; /* sub-page chunks don't work yet.. */ + bits = (size*1024)/min_chunk +1; while (bits > max_bits) { min_chunk *= 2; bits = (bits+1)/2; @@ -880,10 +870,7 @@ static int add_internal_bitmap1(struct supertype *st, void *sbv, int chunk, int else if (chunk < min_chunk) return 0; /* chunk size too small */ - if (st->minor_version == 0) - sb->bitmap_offset = __cpu_to_le32(-64*2); - else - sb->bitmap_offset = __cpu_to_le32(2); + sb->bitmap_offset = __cpu_to_le32(2); sb->feature_map = __cpu_to_le32(__le32_to_cpu(sb->feature_map) | 1); memset(bms, sizeof(*bms), 0); @@ -892,7 +879,7 @@ static int add_internal_bitmap1(struct supertype *st, void *sbv, int chunk, int uuid_from_super1((int*)bms->uuid, sb); bms->chunksize = __cpu_to_le32(chunk); bms->daemon_sleep = __cpu_to_le32(delay); - bms->sync_size = __cpu_to_le64(size); + bms->sync_size = __cpu_to_le64(size<<1); bms->write_behind = __cpu_to_le32(write_behind); return 1; @@ -901,40 +888,21 @@ static int add_internal_bitmap1(struct supertype *st, void *sbv, int chunk, int void locate_bitmap1(struct supertype *st, int fd) { - unsigned long long dsize; - unsigned long size; unsigned long long offset; + struct mdp_superblock_1 *sb; - switch(st->minor_version){ - case 0: -#ifdef BLKGETSIZE64 - if (ioctl(fd, BLKGETSIZE64, &dsize) != 0) -#endif - { - if (ioctl(fd, BLKGETSIZE, &size)) - return; - else - dsize = ((unsigned long long)size)<<9; - } - - offset = (dsize - 8192) & ~4095ULL; + if (st->ss->load_super(st, fd, (void**)&sb, NULL)) + return; /* no error I hope... */ + offset = __le64_to_cpu(sb->super_offset); + offset += (long) __le32_to_cpu(sb->bitmap_offset); - offset -= 65536; - break; - - case 1: - offset = 1024; - break; - case 2: - offset = 4096+1024; - } - lseek64(fd, offset, 0); + lseek64(fd, offset<<9, 0); } int write_bitmap1(struct supertype *st, int fd, void *sbv) { struct mdp_superblock_1 *sb = sbv; - + bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb)+1024); int rv = 0; int towrite, n; @@ -943,7 +911,8 @@ int write_bitmap1(struct supertype *st, int fd, void *sbv) locate_bitmap1(st, fd); write(fd, ((char*)sb)+1024, sizeof(bitmap_super_t)); - towrite = 62*1024 - sizeof(bitmap_super_t); + towrite = __le64_to_cpu(bms->sync_size) / (__le32_to_cpu(bms->chunksize)>>9); + towrite = (towrite+7) >> 3; /* bits to bytes */ memset(buf, 0xff, sizeof(buf)); while (towrite > 0) { n = towrite; |