Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ac8c3f3d authored by Joe Thornber's avatar Joe Thornber Committed by Alasdair G Kergon
Browse files

dm thin: generate event when metadata threshold passed



Generate a dm event when the amount of remaining thin pool metadata
space falls below a certain level.

The threshold is taken to be a quarter of the size of the metadata
device with a minimum threshold of 4MB.

Signed-off-by: default avatarJoe Thornber <ejt@redhat.com>
Signed-off-by: default avatarAlasdair G Kergon <agk@redhat.com>
parent 2fc48021
Loading
Loading
Loading
Loading
+14 −0
Original line number Original line Diff line number Diff line
@@ -1696,3 +1696,17 @@ void dm_pool_metadata_read_only(struct dm_pool_metadata *pmd)
	dm_bm_set_read_only(pmd->bm);
	dm_bm_set_read_only(pmd->bm);
	up_write(&pmd->root_lock);
	up_write(&pmd->root_lock);
}
}

int dm_pool_register_metadata_threshold(struct dm_pool_metadata *pmd,
					dm_block_t threshold,
					dm_sm_threshold_fn fn,
					void *context)
{
	int r;

	down_write(&pmd->root_lock);
	r = dm_sm_register_threshold_callback(pmd->metadata_sm, threshold, fn, context);
	up_write(&pmd->root_lock);

	return r;
}
+6 −0
Original line number Original line Diff line number Diff line
@@ -8,6 +8,7 @@
#define DM_THIN_METADATA_H
#define DM_THIN_METADATA_H


#include "persistent-data/dm-block-manager.h"
#include "persistent-data/dm-block-manager.h"
#include "persistent-data/dm-space-map.h"


#define THIN_METADATA_BLOCK_SIZE 4096
#define THIN_METADATA_BLOCK_SIZE 4096


@@ -193,6 +194,11 @@ int dm_pool_resize_metadata_dev(struct dm_pool_metadata *pmd, dm_block_t new_siz
 */
 */
void dm_pool_metadata_read_only(struct dm_pool_metadata *pmd);
void dm_pool_metadata_read_only(struct dm_pool_metadata *pmd);


int dm_pool_register_metadata_threshold(struct dm_pool_metadata *pmd,
					dm_block_t threshold,
					dm_sm_threshold_fn fn,
					void *context);

/*----------------------------------------------------------------*/
/*----------------------------------------------------------------*/


#endif
#endif
+38 −0
Original line number Original line Diff line number Diff line
@@ -1281,6 +1281,10 @@ static void process_bio_fail(struct thin_c *tc, struct bio *bio)
	bio_io_error(bio);
	bio_io_error(bio);
}
}


/*
 * FIXME: should we also commit due to size of transaction, measured in
 * metadata blocks?
 */
static int need_commit_due_to_time(struct pool *pool)
static int need_commit_due_to_time(struct pool *pool)
{
{
	return jiffies < pool->last_commit_jiffies ||
	return jiffies < pool->last_commit_jiffies ||
@@ -1909,6 +1913,16 @@ static int parse_pool_features(struct dm_arg_set *as, struct pool_features *pf,
	return r;
	return r;
}
}


static void metadata_low_callback(void *context)
{
	struct pool *pool = context;

	DMWARN("%s: reached low water mark for metadata device: sending event.",
	       dm_device_name(pool->pool_md));

	dm_table_event(pool->ti->table);
}

static sector_t get_metadata_dev_size(struct block_device *bdev)
static sector_t get_metadata_dev_size(struct block_device *bdev)
{
{
	sector_t metadata_dev_size = i_size_read(bdev->bd_inode) >> SECTOR_SHIFT;
	sector_t metadata_dev_size = i_size_read(bdev->bd_inode) >> SECTOR_SHIFT;
@@ -1932,6 +1946,23 @@ static dm_block_t get_metadata_dev_size_in_blocks(struct block_device *bdev)
	return metadata_dev_size;
	return metadata_dev_size;
}
}


/*
 * When a metadata threshold is crossed a dm event is triggered, and
 * userland should respond by growing the metadata device.  We could let
 * userland set the threshold, like we do with the data threshold, but I'm
 * not sure they know enough to do this well.
 */
static dm_block_t calc_metadata_threshold(struct pool_c *pt)
{
	/*
	 * 4M is ample for all ops with the possible exception of thin
	 * device deletion which is harmless if it fails (just retry the
	 * delete after you've grown the device).
	 */
	dm_block_t quarter = get_metadata_dev_size_in_blocks(pt->metadata_dev->bdev) / 4;
	return min((dm_block_t)1024ULL /* 4M */, quarter);
}

/*
/*
 * thin-pool <metadata dev> <data dev>
 * thin-pool <metadata dev> <data dev>
 *	     <data block size (sectors)>
 *	     <data block size (sectors)>
@@ -2065,6 +2096,13 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv)
	}
	}
	ti->private = pt;
	ti->private = pt;


	r = dm_pool_register_metadata_threshold(pt->pool->pmd,
						calc_metadata_threshold(pt),
						metadata_low_callback,
						pool);
	if (r)
		goto out_free_pt;

	pt->callbacks.congested_fn = pool_is_congested;
	pt->callbacks.congested_fn = pool_is_congested;
	dm_table_add_target_callbacks(ti->table, &pt->callbacks);
	dm_table_add_target_callbacks(ti->table, &pt->callbacks);