[09/11] btrfs: add support for write stream IDs
diff mbox

Message ID 1457107853-8689-10-git-send-email-axboe@fb.com
State New
Headers show

Commit Message

Jens Axboe March 4, 2016, 4:10 p.m. UTC
Both buffered and O_DIRECT supported, and support for iterating
the below backing devices for open/close of streams.

Signed-off-by: Jens Axboe <axboe@fb.com>
---
 fs/btrfs/disk-io.c   | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 fs/btrfs/extent_io.c |  1 +
 fs/btrfs/inode.c     |  1 +
 3 files changed, 71 insertions(+)

Comments

Chris Mason March 4, 2016, 8:44 p.m. UTC | #1
On Fri, Mar 04, 2016 at 09:10:51AM -0700, Jens Axboe wrote:
> Both buffered and O_DIRECT supported, and support for iterating
> the below backing devices for open/close of streams.

Looks good to me Jens, we'll just want to double check the dio streamid
is getting passed all the way down through the btrfs maze of dio
mirrors.

Signed-off-by: Chris Mason <clm@fb.com>
--
To unsubscribe from this list: send the line "unsubscribe linux-block" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jens Axboe March 4, 2016, 8:45 p.m. UTC | #2
On 03/04/2016 01:44 PM, Chris Mason wrote:
> On Fri, Mar 04, 2016 at 09:10:51AM -0700, Jens Axboe wrote:
>> Both buffered and O_DIRECT supported, and support for iterating
>> the below backing devices for open/close of streams.
>
> Looks good to me Jens, we'll just want to double check the dio streamid
> is getting passed all the way down through the btrfs maze of dio
> mirrors.

Thanks, yes once we have the blktrace bits cleaned up and done, we can 
run that full stack test and verify that it works as intended.

Patch
diff mbox

diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 4545e2e2ad45..2fd3b4a6bdcd 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1748,6 +1748,72 @@  static int btrfs_congested_fn(void *congested_data, int bdi_bits)
 	return ret;
 }
 
+static int btrfs_streamid_close(struct btrfs_fs_info *info, int id)
+{
+	struct btrfs_device *device;
+
+	mutex_lock(&info->fs_devices->device_list_mutex);
+	list_for_each_entry_rcu(device, &info->fs_devices->devices, dev_list) {
+		struct backing_dev_info *bdi;
+
+		if (!device->bdev)
+			continue;
+
+		bdi = blk_get_backing_dev_info(device->bdev);
+		bdi_streamid_close(bdi, id);
+	}
+	mutex_unlock(&info->fs_devices->device_list_mutex);
+
+	return 0;
+}
+
+static int btrfs_streamid_open(struct btrfs_fs_info *info, int id)
+{
+	struct btrfs_device *device;
+	int ret = -EINVAL;
+
+	mutex_lock(&info->fs_devices->device_list_mutex);
+	list_for_each_entry_rcu(device, &info->fs_devices->devices, dev_list) {
+		struct backing_dev_info *bdi;
+
+		if (!device->bdev)
+			continue;
+
+		bdi = blk_get_backing_dev_info(device->bdev);
+		ret = bdi_streamid_open(bdi, id);
+		if (ret < 0)
+			break;
+	}
+	mutex_unlock(&info->fs_devices->device_list_mutex);
+
+	return ret;
+}
+
+static int btrfs_streamid_open_fn(void *data, unsigned int id)
+{
+	struct btrfs_fs_info *info = (struct btrfs_fs_info *) data;
+	int ret = 0;
+
+	/*
+	 * > 0 is success, return it. If we fail, fall through to
+	 * freeing the ID, if we did set it on a device.
+	 */
+	ret = btrfs_streamid_open(info, id);
+	if (ret > 0)
+		return ret;
+
+	btrfs_streamid_close(info, id);
+	return ret;
+}
+
+static int btrfs_streamid_close_fn(void *data, unsigned int id)
+{
+	struct btrfs_fs_info *info = (struct btrfs_fs_info *) data;
+
+	btrfs_streamid_close(info, id);
+	return 0;
+}
+
 static int setup_bdi(struct btrfs_fs_info *info, struct backing_dev_info *bdi)
 {
 	int err;
@@ -1760,6 +1826,9 @@  static int setup_bdi(struct btrfs_fs_info *info, struct backing_dev_info *bdi)
 	bdi->congested_fn	= btrfs_congested_fn;
 	bdi->congested_data	= info;
 	bdi->capabilities |= BDI_CAP_CGROUP_WRITEBACK;
+	bdi->streamid_open	= btrfs_streamid_open_fn;
+	bdi->streamid_close	= btrfs_streamid_close_fn;
+	bdi->streamid_data	= info;
 	return 0;
 }
 
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index 392592dc7010..0f1507af8266 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -2808,6 +2808,7 @@  static int submit_extent_page(int rw, struct extent_io_tree *tree,
 	bio_add_page(bio, page, page_size, offset);
 	bio->bi_end_io = end_io_func;
 	bio->bi_private = tree;
+	bio_set_streamid(bio, inode_streamid(page->mapping->host));
 	if (wbc) {
 		wbc_init_bio(wbc, bio);
 		wbc_account_io(wbc, page, page_size);
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index d96f5cf38a2d..77661a1f9e5e 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -8338,6 +8338,7 @@  static void btrfs_submit_direct(int rw, struct bio *dio_bio,
 	atomic_set(&dip->pending_bios, 0);
 	btrfs_bio = btrfs_io_bio(io_bio);
 	btrfs_bio->logical = file_offset;
+	bio_set_streamid(io_bio, bio_get_streamid(dio_bio));
 
 	if (write) {
 		io_bio->bi_end_io = btrfs_endio_direct_write;