+static unsigned long long
+super_1_rdev_size_change(mdk_rdev_t *rdev, unsigned long long size)
+{
+ struct mdp_superblock_1 *sb;
+ unsigned long long max_size;
+ if (size && size < rdev->mddev->size)
+ return 0; /* component must fit device */
+ size *= 2; /* convert to sectors */
+ if (rdev->sb_offset < rdev->data_offset/2) {
+ /* minor versions 1 and 2; superblock before data */
+ max_size = (rdev->bdev->bd_inode->i_size >> 9);
+ max_size -= rdev->data_offset;
+ if (!size || size > max_size)
+ size = max_size;
+ } else if (rdev->mddev->bitmap_offset) {
+ /* minor version 0 with bitmap we can't move */
+ return 0;
+ } else {
+ /* minor version 0; superblock after data */
+ sector_t sb_offset;
+ sb_offset = (rdev->bdev->bd_inode->i_size >> 9) - 8*2;
+ sb_offset &= ~(sector_t)(4*2 - 1);
+ max_size = rdev->size*2 + sb_offset - rdev->sb_offset*2;
+ if (!size || size > max_size)
+ size = max_size;
+ rdev->sb_offset = sb_offset/2;
+ }
+ sb = (struct mdp_superblock_1 *) page_address(rdev->sb_page);
+ sb->data_size = cpu_to_le64(size);
+ sb->super_offset = rdev->sb_offset*2;
+ sb->sb_csum = calc_sb_1_csum(sb);
+ md_super_write(rdev->mddev, rdev, rdev->sb_offset << 1, rdev->sb_size,
+ rdev->sb_page);
+ md_super_wait(rdev->mddev);
+ return size/2; /* kB for sysfs */
+}