* [PATCH 0/4] Device helper cleanups
@ 2017-07-18 15:40 David Sterba
2017-07-18 15:40 ` [PATCH 1/4] btrfs: merge alloc_device helpers David Sterba
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: David Sterba @ 2017-07-18 15:40 UTC (permalink / raw)
To: linux-btrfs; +Cc: David Sterba
David Sterba (4):
btrfs: merge alloc_device helpers
btrfs: refactor find_device helper
btrfs: split write_dev_supers to two functions
btrfs: use named constant for bdev blocksize
fs/btrfs/check-integrity.c | 6 +-
fs/btrfs/disk-io.c | 136 +++++++++++++++++++++++++--------------------
fs/btrfs/disk-io.h | 8 +++
fs/btrfs/volumes.c | 61 +++++++++-----------
4 files changed, 115 insertions(+), 96 deletions(-)
--
2.13.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 1/4] btrfs: merge alloc_device helpers
2017-07-18 15:40 [PATCH 0/4] Device helper cleanups David Sterba
@ 2017-07-18 15:40 ` David Sterba
2017-07-18 15:40 ` [PATCH 2/4] btrfs: refactor find_device helper David Sterba
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: David Sterba @ 2017-07-18 15:40 UTC (permalink / raw)
To: linux-btrfs; +Cc: David Sterba
There are two helpers called in chain from one location, we can merge the
functionaliy.
Originally, alloc_fs_devices could fill the device uuid randomly if we
we didn't give the uuid buffer. This happens for seed devices but the
fsid is generated in btrfs_prepare_sprout, so we can remove it.
Signed-off-by: David Sterba <dsterba@suse.com>
---
fs/btrfs/volumes.c | 36 +++++++++++-------------------------
1 file changed, 11 insertions(+), 25 deletions(-)
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index c95f018d4a1e..39deba4e88e3 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -152,7 +152,15 @@ struct list_head *btrfs_get_fs_uuids(void)
return &fs_uuids;
}
-static struct btrfs_fs_devices *__alloc_fs_devices(void)
+/*
+ * alloc_fs_devices - allocate struct btrfs_fs_devices
+ * @fsid: if not NULL, copy the uuid to fs_devices::fsid
+ *
+ * Return a pointer to a new struct btrfs_fs_devices on success, or ERR_PTR().
+ * The returned struct is not linked onto any lists and can be destroyed with
+ * kfree() right away.
+ */
+static struct btrfs_fs_devices *alloc_fs_devices(const u8 *fsid)
{
struct btrfs_fs_devices *fs_devs;
@@ -166,31 +174,8 @@ static struct btrfs_fs_devices *__alloc_fs_devices(void)
INIT_LIST_HEAD(&fs_devs->resized_devices);
INIT_LIST_HEAD(&fs_devs->alloc_list);
INIT_LIST_HEAD(&fs_devs->list);
-
- return fs_devs;
-}
-
-/**
- * alloc_fs_devices - allocate struct btrfs_fs_devices
- * @fsid: a pointer to UUID for this FS. If NULL a new UUID is
- * generated.
- *
- * Return: a pointer to a new &struct btrfs_fs_devices on success;
- * ERR_PTR() on error. Returned struct is not linked onto any lists and
- * can be destroyed with kfree() right away.
- */
-static struct btrfs_fs_devices *alloc_fs_devices(const u8 *fsid)
-{
- struct btrfs_fs_devices *fs_devs;
-
- fs_devs = __alloc_fs_devices();
- if (IS_ERR(fs_devs))
- return fs_devs;
-
if (fsid)
memcpy(fs_devs->fsid, fsid, BTRFS_FSID_SIZE);
- else
- generate_random_uuid(fs_devs->fsid);
return fs_devs;
}
@@ -2202,7 +2187,7 @@ static int btrfs_prepare_sprout(struct btrfs_fs_info *fs_info)
if (!fs_devices->seeding)
return -EINVAL;
- seed_devices = __alloc_fs_devices();
+ seed_devices = alloc_fs_devices(NULL);
if (IS_ERR(seed_devices))
return PTR_ERR(seed_devices);
@@ -6568,6 +6553,7 @@ static struct btrfs_fs_devices *open_seed_devices(struct btrfs_fs_info *fs_info,
int ret;
BUG_ON(!mutex_is_locked(&uuid_mutex));
+ ASSERT(fsid);
fs_devices = fs_info->fs_devices->seed;
while (fs_devices) {
--
2.13.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 2/4] btrfs: refactor find_device helper
2017-07-18 15:40 [PATCH 0/4] Device helper cleanups David Sterba
2017-07-18 15:40 ` [PATCH 1/4] btrfs: merge alloc_device helpers David Sterba
@ 2017-07-18 15:40 ` David Sterba
2017-07-18 15:40 ` [PATCH 3/4] btrfs: split write_dev_supers to two functions David Sterba
2017-07-18 15:40 ` [PATCH 4/4] btrfs: use named constant for bdev blocksize David Sterba
3 siblings, 0 replies; 5+ messages in thread
From: David Sterba @ 2017-07-18 15:40 UTC (permalink / raw)
To: linux-btrfs; +Cc: David Sterba
Polish the helper:
* drop underscores, no special meaning here
* pass fs_devices, as this is what the API implements
* drop noinline, no apparent reason for such simple helper
* constify uuid
* add comment
Signed-off-by: David Sterba <dsterba@suse.com>
---
fs/btrfs/volumes.c | 19 +++++++++++++------
1 file changed, 13 insertions(+), 6 deletions(-)
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 39deba4e88e3..c3eafc8367d5 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -254,9 +254,17 @@ static struct btrfs_device *__alloc_device(void)
return dev;
}
-static noinline struct btrfs_device *__find_device(struct list_head *head,
- u64 devid, u8 *uuid)
+/*
+ * Find a device specified by @devid or @uuid in the list of @fs_devices, or
+ * return NULL.
+ *
+ * If devid and uuid are both specified, the match must be exact, otherwise
+ * only devid is used.
+ */
+static struct btrfs_device *find_device(struct btrfs_fs_devices *fs_devices,
+ u64 devid, const u8 *uuid)
{
+ struct list_head *head = &fs_devices->devices;
struct btrfs_device *dev;
list_for_each_entry(dev, head, dev_list) {
@@ -621,8 +629,8 @@ static noinline int device_list_add(const char *path,
device = NULL;
} else {
- device = __find_device(&fs_devices->devices, devid,
- disk_super->dev_item.uuid);
+ device = find_device(fs_devices, devid,
+ disk_super->dev_item.uuid);
}
if (!device) {
@@ -6280,8 +6288,7 @@ struct btrfs_device *btrfs_find_device(struct btrfs_fs_info *fs_info, u64 devid,
while (cur_devices) {
if (!fsid ||
!memcmp(cur_devices->fsid, fsid, BTRFS_UUID_SIZE)) {
- device = __find_device(&cur_devices->devices,
- devid, uuid);
+ device = find_device(cur_devices, devid, uuid);
if (device)
return device;
}
--
2.13.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 3/4] btrfs: split write_dev_supers to two functions
2017-07-18 15:40 [PATCH 0/4] Device helper cleanups David Sterba
2017-07-18 15:40 ` [PATCH 1/4] btrfs: merge alloc_device helpers David Sterba
2017-07-18 15:40 ` [PATCH 2/4] btrfs: refactor find_device helper David Sterba
@ 2017-07-18 15:40 ` David Sterba
2017-07-18 15:40 ` [PATCH 4/4] btrfs: use named constant for bdev blocksize David Sterba
3 siblings, 0 replies; 5+ messages in thread
From: David Sterba @ 2017-07-18 15:40 UTC (permalink / raw)
To: linux-btrfs; +Cc: David Sterba
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: David Sterba <dsterba@suse.com>
---
fs/btrfs/disk-io.c | 129 ++++++++++++++++++++++++++++++-----------------------
1 file changed, 73 insertions(+), 56 deletions(-)
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 075beedb4352..df4772918ebb 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -3378,19 +3378,17 @@ struct buffer_head *btrfs_read_dev_super(struct block_device *bdev)
}
/*
- * this should be called twice, once with wait == 0 and
- * once with wait == 1. When wait == 0 is done, all the buffer heads
- * we write are pinned.
+ * Write superblock @sb to the @device. Do not wait for completion, all the
+ * buffer heads we write are pinned.
*
- * They are released when wait == 1 is done.
- * max_mirrors must be the same for both runs, and it indicates how
- * many supers on this one device should be written.
+ * Write @max_mirrors copies of the superblock, where 0 means default that fit
+ * the expected device size at commit time. Note that max_mirrors must be
+ * 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,
- struct btrfs_super_block *sb,
- int wait, int max_mirrors)
+ struct btrfs_super_block *sb, int max_mirrors)
{
struct buffer_head *bh;
int i;
@@ -3408,57 +3406,33 @@ static int write_dev_supers(struct btrfs_device *device,
device->commit_total_bytes)
break;
- if (wait) {
- 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++;
+ btrfs_set_super_bytenr(sb, bytenr);
- /* drop our reference */
- brelse(bh);
+ 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);
- /* drop the reference from the wait == 0 run */
- brelse(bh);
+ /* 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;
- } 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 */
- get_bh(bh);
+ /* one reference for submit_bh */
+ get_bh(bh);
- set_buffer_uptodate(bh);
- lock_buffer(bh);
- bh->b_end_io = btrfs_end_buffer_write_sync;
- bh->b_private = device;
- }
+ set_buffer_uptodate(bh);
+ lock_buffer(bh);
+ bh->b_end_io = btrfs_end_buffer_write_sync;
+ bh->b_private = device;
/*
* we fua the first super. The others we allow
@@ -3477,6 +3451,49 @@ static int write_dev_supers(struct btrfs_device *device,
}
/*
+ * 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
* for the barrier when it is done
*/
@@ -3737,7 +3754,7 @@ int write_all_supers(struct btrfs_fs_info *fs_info, int max_mirrors)
flags = btrfs_super_flags(sb);
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)
total_errors++;
}
@@ -3760,7 +3777,7 @@ int write_all_supers(struct btrfs_fs_info *fs_info, int max_mirrors)
if (!dev->in_fs_metadata || !dev->writeable)
continue;
- ret = write_dev_supers(dev, sb, 1, max_mirrors);
+ ret = wait_dev_supers(dev, max_mirrors);
if (ret)
total_errors++;
}
--
2.13.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 4/4] btrfs: use named constant for bdev blocksize
2017-07-18 15:40 [PATCH 0/4] Device helper cleanups David Sterba
` (2 preceding siblings ...)
2017-07-18 15:40 ` [PATCH 3/4] btrfs: split write_dev_supers to two functions David Sterba
@ 2017-07-18 15:40 ` David Sterba
3 siblings, 0 replies; 5+ messages in thread
From: David Sterba @ 2017-07-18 15:40 UTC (permalink / raw)
To: linux-btrfs; +Cc: David Sterba
Superblock is read and written using buffer heads, we need to set the
bdev blocksize. The magic constant has been hardcoded in several places,
so replace it with a named constant.
Signed-off-by: David Sterba <dsterba@suse.com>
---
fs/btrfs/check-integrity.c | 6 +++---
fs/btrfs/disk-io.c | 11 ++++++-----
fs/btrfs/disk-io.h | 8 ++++++++
fs/btrfs/volumes.c | 6 +++---
4 files changed, 20 insertions(+), 11 deletions(-)
diff --git a/fs/btrfs/check-integrity.c b/fs/btrfs/check-integrity.c
index e3b1d08dd03c..060893141fe9 100644
--- a/fs/btrfs/check-integrity.c
+++ b/fs/btrfs/check-integrity.c
@@ -795,12 +795,12 @@ static int btrfsic_process_superblock_dev_mirror(
dev_bytenr = btrfs_sb_offset(superblock_mirror_num);
if (dev_bytenr + BTRFS_SUPER_INFO_SIZE > device->commit_total_bytes)
return -1;
- bh = __bread(superblock_bdev, dev_bytenr / 4096,
+ bh = __bread(superblock_bdev, dev_bytenr / BTRFS_BDEV_BLOCKSIZE,
BTRFS_SUPER_INFO_SIZE);
if (NULL == bh)
return -1;
super_tmp = (struct btrfs_super_block *)
- (bh->b_data + (dev_bytenr & 4095));
+ (bh->b_data + (dev_bytenr & (BTRFS_BDEV_BLOCKSIZE - 1)));
if (btrfs_super_bytenr(super_tmp) != dev_bytenr ||
btrfs_super_magic(super_tmp) != BTRFS_MAGIC ||
@@ -2758,7 +2758,7 @@ int btrfsic_submit_bh(int op, int op_flags, struct buffer_head *bh)
(op == REQ_OP_WRITE) && bh->b_size > 0) {
u64 dev_bytenr;
- dev_bytenr = 4096 * bh->b_blocknr;
+ dev_bytenr = BTRFS_BDEV_BLOCKSIZE * bh->b_blocknr;
if (dev_state->state->print_mask &
BTRFSIC_PRINT_MASK_SUBMIT_BIO_BH)
pr_info("submit_bh(op=0x%x,0x%x, blocknr=%llu (bytenr %llu), size=%zu, data=%p, bdev=%p)\n",
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index df4772918ebb..aa94b6578c36 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -2694,8 +2694,8 @@ int open_ctree(struct super_block *sb,
btrfs_init_balance(fs_info);
btrfs_init_async_reclaim_work(&fs_info->async_reclaim_work);
- sb->s_blocksize = 4096;
- sb->s_blocksize_bits = blksize_bits(4096);
+ sb->s_blocksize = BTRFS_BDEV_BLOCKSIZE;
+ sb->s_blocksize_bits = blksize_bits(BTRFS_BDEV_BLOCKSIZE);
btrfs_init_btree_inode(fs_info);
@@ -3321,7 +3321,7 @@ int btrfs_read_dev_one_super(struct block_device *bdev, int copy_num,
if (bytenr + BTRFS_SUPER_INFO_SIZE >= i_size_read(bdev->bd_inode))
return -EINVAL;
- bh = __bread(bdev, bytenr / 4096, BTRFS_SUPER_INFO_SIZE);
+ bh = __bread(bdev, bytenr / BTRFS_BDEV_BLOCKSIZE, BTRFS_SUPER_INFO_SIZE);
/*
* If we fail to read from the underlying devices, as of now
* the best option we have is to mark it EIO.
@@ -3414,7 +3414,7 @@ static int write_dev_supers(struct btrfs_device *device,
btrfs_csum_final(crc, sb->csum);
/* One reference for us, and we leave it for the caller */
- bh = __getblk(device->bdev, bytenr / 4096,
+ bh = __getblk(device->bdev, bytenr / BTRFS_BDEV_BLOCKSIZE,
BTRFS_SUPER_INFO_SIZE);
if (!bh) {
btrfs_err(device->fs_info,
@@ -3473,7 +3473,8 @@ static int wait_dev_supers(struct btrfs_device *device, int max_mirrors)
device->commit_total_bytes)
break;
- bh = __find_get_block(device->bdev, bytenr / 4096,
+ bh = __find_get_block(device->bdev,
+ bytenr / BTRFS_BDEV_BLOCKSIZE,
BTRFS_SUPER_INFO_SIZE);
if (!bh) {
errors++;
diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h
index 4654d129aa76..995d0aa0abe4 100644
--- a/fs/btrfs/disk-io.h
+++ b/fs/btrfs/disk-io.h
@@ -25,6 +25,14 @@
#define BTRFS_SUPER_MIRROR_MAX 3
#define BTRFS_SUPER_MIRROR_SHIFT 12
+/*
+ * Fixed blocksize for all devices, applies to specific ways of reading
+ * metadata like superblock. Must meet the set_blocksize requirements.
+ *
+ * Do not change.
+ */
+#define BTRFS_BDEV_BLOCKSIZE (4096)
+
enum btrfs_wq_endio_type {
BTRFS_WQ_ENDIO_DATA = 0,
BTRFS_WQ_ENDIO_METADATA = 1,
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index c3eafc8367d5..327b05c14592 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -303,7 +303,7 @@ btrfs_get_bdev_and_sb(const char *device_path, fmode_t flags, void *holder,
if (flush)
filemap_write_and_wait((*bdev)->bd_inode->i_mapping);
- ret = set_blocksize(*bdev, 4096);
+ ret = set_blocksize(*bdev, BTRFS_BDEV_BLOCKSIZE);
if (ret) {
blkdev_put(*bdev, flags);
goto error;
@@ -2400,7 +2400,7 @@ int btrfs_init_new_device(struct btrfs_fs_info *fs_info, const char *device_path
device->is_tgtdev_for_dev_replace = 0;
device->mode = FMODE_EXCL;
device->dev_stats_valid = 1;
- set_blocksize(device->bdev, 4096);
+ set_blocksize(device->bdev, BTRFS_BDEV_BLOCKSIZE);
if (seeding_dev) {
sb->s_flags &= ~MS_RDONLY;
@@ -2605,7 +2605,7 @@ int btrfs_init_dev_replace_tgtdev(struct btrfs_fs_info *fs_info,
device->is_tgtdev_for_dev_replace = 1;
device->mode = FMODE_EXCL;
device->dev_stats_valid = 1;
- set_blocksize(device->bdev, 4096);
+ set_blocksize(device->bdev, BTRFS_BDEV_BLOCKSIZE);
device->fs_devices = fs_info->fs_devices;
list_add(&device->dev_list, &fs_info->fs_devices->devices);
fs_info->fs_devices->num_devices++;
--
2.13.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2017-07-18 15:41 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-07-18 15:40 [PATCH 0/4] Device helper cleanups David Sterba
2017-07-18 15:40 ` [PATCH 1/4] btrfs: merge alloc_device helpers David Sterba
2017-07-18 15:40 ` [PATCH 2/4] btrfs: refactor find_device helper David Sterba
2017-07-18 15:40 ` [PATCH 3/4] btrfs: split write_dev_supers to two functions David Sterba
2017-07-18 15:40 ` [PATCH 4/4] btrfs: use named constant for bdev blocksize David Sterba
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.