Commit abbb3b8e authored by David Sterba's avatar David Sterba

btrfs: split write_dev_supers to two functions

There are two independent parts, one that writes the superblocks and
another that waits for completion. No functional changes, but cleanups,
reformatting and comment updates.
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent 35c70103
...@@ -3373,19 +3373,17 @@ struct buffer_head *btrfs_read_dev_super(struct block_device *bdev) ...@@ -3373,19 +3373,17 @@ struct buffer_head *btrfs_read_dev_super(struct block_device *bdev)
} }
/* /*
* this should be called twice, once with wait == 0 and * Write superblock @sb to the @device. Do not wait for completion, all the
* once with wait == 1. When wait == 0 is done, all the buffer heads * buffer heads we write are pinned.
* we write are pinned.
* *
* They are released when wait == 1 is done. * Write @max_mirrors copies of the superblock, where 0 means default that fit
* max_mirrors must be the same for both runs, and it indicates how * the expected device size at commit time. Note that max_mirrors must be
* many supers on this one device should be written. * same for write and wait phases.
* *
* max_mirrors == 0 means to write them all. * Return number of errors when buffer head is not found or submission fails.
*/ */
static int write_dev_supers(struct btrfs_device *device, static int write_dev_supers(struct btrfs_device *device,
struct btrfs_super_block *sb, struct btrfs_super_block *sb, int max_mirrors)
int wait, int max_mirrors)
{ {
struct buffer_head *bh; struct buffer_head *bh;
int i; int i;
...@@ -3403,57 +3401,33 @@ static int write_dev_supers(struct btrfs_device *device, ...@@ -3403,57 +3401,33 @@ static int write_dev_supers(struct btrfs_device *device,
device->commit_total_bytes) device->commit_total_bytes)
break; break;
if (wait) { btrfs_set_super_bytenr(sb, bytenr);
bh = __find_get_block(device->bdev, bytenr / 4096,
BTRFS_SUPER_INFO_SIZE);
if (!bh) {
errors++;
continue;
}
wait_on_buffer(bh);
if (!buffer_uptodate(bh))
errors++;
/* drop our reference */ crc = ~(u32)0;
brelse(bh); crc = btrfs_csum_data((const char *)sb + BTRFS_CSUM_SIZE, crc,
BTRFS_SUPER_INFO_SIZE - BTRFS_CSUM_SIZE);
btrfs_csum_final(crc, sb->csum);
/* drop the reference from the wait == 0 run */ /* One reference for us, and we leave it for the caller */
brelse(bh); bh = __getblk(device->bdev, bytenr / 4096,
BTRFS_SUPER_INFO_SIZE);
if (!bh) {
btrfs_err(device->fs_info,
"couldn't get super buffer head for bytenr %llu",
bytenr);
errors++;
continue; continue;
} else { }
btrfs_set_super_bytenr(sb, bytenr);
crc = ~(u32)0;
crc = btrfs_csum_data((const char *)sb +
BTRFS_CSUM_SIZE, crc,
BTRFS_SUPER_INFO_SIZE -
BTRFS_CSUM_SIZE);
btrfs_csum_final(crc, sb->csum);
/*
* one reference for us, and we leave it for the
* caller
*/
bh = __getblk(device->bdev, bytenr / 4096,
BTRFS_SUPER_INFO_SIZE);
if (!bh) {
btrfs_err(device->fs_info,
"couldn't get super buffer head for bytenr %llu",
bytenr);
errors++;
continue;
}
memcpy(bh->b_data, sb, BTRFS_SUPER_INFO_SIZE); memcpy(bh->b_data, sb, BTRFS_SUPER_INFO_SIZE);
/* one reference for submit_bh */ /* one reference for submit_bh */
get_bh(bh); get_bh(bh);
set_buffer_uptodate(bh); set_buffer_uptodate(bh);
lock_buffer(bh); lock_buffer(bh);
bh->b_end_io = btrfs_end_buffer_write_sync; bh->b_end_io = btrfs_end_buffer_write_sync;
bh->b_private = device; bh->b_private = device;
}
/* /*
* we fua the first super. The others we allow * we fua the first super. The others we allow
...@@ -3471,6 +3445,49 @@ static int write_dev_supers(struct btrfs_device *device, ...@@ -3471,6 +3445,49 @@ static int write_dev_supers(struct btrfs_device *device,
return errors < i ? 0 : -1; return errors < i ? 0 : -1;
} }
/*
* Wait for write completion of superblocks done by write_dev_supers,
* @max_mirrors same for write and wait phases.
*
* Return number of errors when buffer head is not found or not marked up to
* date.
*/
static int wait_dev_supers(struct btrfs_device *device, int max_mirrors)
{
struct buffer_head *bh;
int i;
int errors = 0;
u64 bytenr;
if (max_mirrors == 0)
max_mirrors = BTRFS_SUPER_MIRROR_MAX;
for (i = 0; i < max_mirrors; i++) {
bytenr = btrfs_sb_offset(i);
if (bytenr + BTRFS_SUPER_INFO_SIZE >=
device->commit_total_bytes)
break;
bh = __find_get_block(device->bdev, bytenr / 4096,
BTRFS_SUPER_INFO_SIZE);
if (!bh) {
errors++;
continue;
}
wait_on_buffer(bh);
if (!buffer_uptodate(bh))
errors++;
/* drop our reference */
brelse(bh);
/* drop the reference from the writing run */
brelse(bh);
}
return errors < i ? 0 : -1;
}
/* /*
* endio for the write_dev_flush, this will wake anyone waiting * endio for the write_dev_flush, this will wake anyone waiting
* for the barrier when it is done * for the barrier when it is done
...@@ -3668,7 +3685,7 @@ int write_all_supers(struct btrfs_fs_info *fs_info, int max_mirrors) ...@@ -3668,7 +3685,7 @@ int write_all_supers(struct btrfs_fs_info *fs_info, int max_mirrors)
flags = btrfs_super_flags(sb); flags = btrfs_super_flags(sb);
btrfs_set_super_flags(sb, flags | BTRFS_HEADER_FLAG_WRITTEN); btrfs_set_super_flags(sb, flags | BTRFS_HEADER_FLAG_WRITTEN);
ret = write_dev_supers(dev, sb, 0, max_mirrors); ret = write_dev_supers(dev, sb, max_mirrors);
if (ret) if (ret)
total_errors++; total_errors++;
} }
...@@ -3691,7 +3708,7 @@ int write_all_supers(struct btrfs_fs_info *fs_info, int max_mirrors) ...@@ -3691,7 +3708,7 @@ int write_all_supers(struct btrfs_fs_info *fs_info, int max_mirrors)
if (!dev->in_fs_metadata || !dev->writeable) if (!dev->in_fs_metadata || !dev->writeable)
continue; continue;
ret = write_dev_supers(dev, sb, 1, max_mirrors); ret = wait_dev_supers(dev, max_mirrors);
if (ret) if (ret)
total_errors++; total_errors++;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment