dm thin: commit before gathering status
Commit outstanding metadata before returning the status for a dm thin pool so that the numbers reported are as up-to-date as possible. The commit is not performed if the device is suspended or if the DM_NOFLUSH_FLAG is supplied by userspace and passed to the target through a new 'status_flags' parameter in the target's dm_status_fn. The userspace dmsetup tool will support the --noflush flag with the 'dmsetup status' and 'dmsetup wait' commands from version 1.02.76 onwards. Tested-by: Mike Snitzer <snitzer@redhat.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com>
This commit is contained in:
parent
e49e582965
commit
1f4e0ff079
15 changed files with 35 additions and 20 deletions
|
@ -1733,7 +1733,7 @@ static int crypt_map(struct dm_target *ti, struct bio *bio,
|
|||
}
|
||||
|
||||
static int crypt_status(struct dm_target *ti, status_type_t type,
|
||||
char *result, unsigned int maxlen)
|
||||
unsigned status_flags, char *result, unsigned maxlen)
|
||||
{
|
||||
struct crypt_config *cc = ti->private;
|
||||
unsigned int sz = 0;
|
||||
|
|
|
@ -295,7 +295,7 @@ static int delay_map(struct dm_target *ti, struct bio *bio,
|
|||
}
|
||||
|
||||
static int delay_status(struct dm_target *ti, status_type_t type,
|
||||
char *result, unsigned maxlen)
|
||||
unsigned status_flags, char *result, unsigned maxlen)
|
||||
{
|
||||
struct delay_c *dc = ti->private;
|
||||
int sz = 0;
|
||||
|
|
|
@ -333,7 +333,7 @@ static int flakey_end_io(struct dm_target *ti, struct bio *bio,
|
|||
}
|
||||
|
||||
static int flakey_status(struct dm_target *ti, status_type_t type,
|
||||
char *result, unsigned int maxlen)
|
||||
unsigned status_flags, char *result, unsigned maxlen)
|
||||
{
|
||||
unsigned sz = 0;
|
||||
struct flakey_c *fc = ti->private;
|
||||
|
|
|
@ -1054,6 +1054,7 @@ static void retrieve_status(struct dm_table *table,
|
|||
char *outbuf, *outptr;
|
||||
status_type_t type;
|
||||
size_t remaining, len, used = 0;
|
||||
unsigned status_flags = 0;
|
||||
|
||||
outptr = outbuf = get_result_buffer(param, param_size, &len);
|
||||
|
||||
|
@ -1090,7 +1091,9 @@ static void retrieve_status(struct dm_table *table,
|
|||
|
||||
/* Get the status/table string from the target driver */
|
||||
if (ti->type->status) {
|
||||
if (ti->type->status(ti, type, outptr, remaining)) {
|
||||
if (param->flags & DM_NOFLUSH_FLAG)
|
||||
status_flags |= DM_STATUS_NOFLUSH_FLAG;
|
||||
if (ti->type->status(ti, type, status_flags, outptr, remaining)) {
|
||||
param->flags |= DM_BUFFER_FULL_FLAG;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -96,7 +96,7 @@ static int linear_map(struct dm_target *ti, struct bio *bio,
|
|||
}
|
||||
|
||||
static int linear_status(struct dm_target *ti, status_type_t type,
|
||||
char *result, unsigned int maxlen)
|
||||
unsigned status_flags, char *result, unsigned maxlen)
|
||||
{
|
||||
struct linear_c *lc = (struct linear_c *) ti->private;
|
||||
|
||||
|
|
|
@ -1378,7 +1378,7 @@ static void multipath_resume(struct dm_target *ti)
|
|||
* num_paths num_selector_args [path_dev [selector_args]* ]+ ]+
|
||||
*/
|
||||
static int multipath_status(struct dm_target *ti, status_type_t type,
|
||||
char *result, unsigned int maxlen)
|
||||
unsigned status_flags, char *result, unsigned maxlen)
|
||||
{
|
||||
int sz = 0;
|
||||
unsigned long flags;
|
||||
|
|
|
@ -1081,7 +1081,7 @@ static int raid_map(struct dm_target *ti, struct bio *bio, union map_info *map_c
|
|||
}
|
||||
|
||||
static int raid_status(struct dm_target *ti, status_type_t type,
|
||||
char *result, unsigned maxlen)
|
||||
unsigned status_flags, char *result, unsigned maxlen)
|
||||
{
|
||||
struct raid_set *rs = ti->private;
|
||||
unsigned raid_param_cnt = 1; /* at least 1 for chunksize */
|
||||
|
|
|
@ -1367,7 +1367,7 @@ static char device_status_char(struct mirror *m)
|
|||
|
||||
|
||||
static int mirror_status(struct dm_target *ti, status_type_t type,
|
||||
char *result, unsigned int maxlen)
|
||||
unsigned status_flags, char *result, unsigned maxlen)
|
||||
{
|
||||
unsigned int m, sz = 0;
|
||||
struct mirror_set *ms = (struct mirror_set *) ti->private;
|
||||
|
|
|
@ -1849,7 +1849,7 @@ static void snapshot_merge_resume(struct dm_target *ti)
|
|||
}
|
||||
|
||||
static int snapshot_status(struct dm_target *ti, status_type_t type,
|
||||
char *result, unsigned int maxlen)
|
||||
unsigned status_flags, char *result, unsigned maxlen)
|
||||
{
|
||||
unsigned sz = 0;
|
||||
struct dm_snapshot *snap = ti->private;
|
||||
|
@ -2151,8 +2151,8 @@ static void origin_resume(struct dm_target *ti)
|
|||
ti->max_io_len = get_origin_minimum_chunksize(dev->bdev);
|
||||
}
|
||||
|
||||
static int origin_status(struct dm_target *ti, status_type_t type, char *result,
|
||||
unsigned int maxlen)
|
||||
static int origin_status(struct dm_target *ti, status_type_t type,
|
||||
unsigned status_flags, char *result, unsigned maxlen)
|
||||
{
|
||||
struct dm_dev *dev = ti->private;
|
||||
|
||||
|
|
|
@ -311,8 +311,8 @@ static int stripe_map(struct dm_target *ti, struct bio *bio,
|
|||
*
|
||||
*/
|
||||
|
||||
static int stripe_status(struct dm_target *ti,
|
||||
status_type_t type, char *result, unsigned int maxlen)
|
||||
static int stripe_status(struct dm_target *ti, status_type_t type,
|
||||
unsigned status_flags, char *result, unsigned maxlen)
|
||||
{
|
||||
struct stripe_c *sc = (struct stripe_c *) ti->private;
|
||||
char buffer[sc->stripes + 1];
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
#include "dm-thin-metadata.h"
|
||||
#include "dm.h"
|
||||
|
||||
#include <linux/device-mapper.h>
|
||||
#include <linux/dm-io.h>
|
||||
|
@ -2619,7 +2620,7 @@ static void emit_flags(struct pool_features *pf, char *result,
|
|||
* <used data sectors>/<total data sectors> <held metadata root>
|
||||
*/
|
||||
static int pool_status(struct dm_target *ti, status_type_t type,
|
||||
char *result, unsigned maxlen)
|
||||
unsigned status_flags, char *result, unsigned maxlen)
|
||||
{
|
||||
int r;
|
||||
unsigned sz = 0;
|
||||
|
@ -2641,6 +2642,10 @@ static int pool_status(struct dm_target *ti, status_type_t type,
|
|||
break;
|
||||
}
|
||||
|
||||
/* Commit to ensure statistics aren't out-of-date */
|
||||
if (!(status_flags & DM_STATUS_NOFLUSH_FLAG) && !dm_suspended(ti))
|
||||
(void) commit_or_fallback(pool);
|
||||
|
||||
r = dm_pool_get_metadata_transaction_id(pool->pmd,
|
||||
&transaction_id);
|
||||
if (r)
|
||||
|
@ -2968,7 +2973,7 @@ static void thin_postsuspend(struct dm_target *ti)
|
|||
* <nr mapped sectors> <highest mapped sector>
|
||||
*/
|
||||
static int thin_status(struct dm_target *ti, status_type_t type,
|
||||
char *result, unsigned maxlen)
|
||||
unsigned status_flags, char *result, unsigned maxlen)
|
||||
{
|
||||
int r;
|
||||
ssize_t sz = 0;
|
||||
|
|
|
@ -515,7 +515,7 @@ static int verity_map(struct dm_target *ti, struct bio *bio,
|
|||
* Status: V (valid) or C (corruption found)
|
||||
*/
|
||||
static int verity_status(struct dm_target *ti, status_type_t type,
|
||||
char *result, unsigned maxlen)
|
||||
unsigned status_flags, char *result, unsigned maxlen)
|
||||
{
|
||||
struct dm_verity *v = ti->private;
|
||||
unsigned sz = 0;
|
||||
|
|
|
@ -22,6 +22,11 @@
|
|||
#define DM_SUSPEND_LOCKFS_FLAG (1 << 0)
|
||||
#define DM_SUSPEND_NOFLUSH_FLAG (1 << 1)
|
||||
|
||||
/*
|
||||
* Status feature flags
|
||||
*/
|
||||
#define DM_STATUS_NOFLUSH_FLAG (1 << 0)
|
||||
|
||||
/*
|
||||
* Type of table and mapped_device's mempool
|
||||
*/
|
||||
|
|
|
@ -72,7 +72,7 @@ typedef int (*dm_preresume_fn) (struct dm_target *ti);
|
|||
typedef void (*dm_resume_fn) (struct dm_target *ti);
|
||||
|
||||
typedef int (*dm_status_fn) (struct dm_target *ti, status_type_t status_type,
|
||||
char *result, unsigned int maxlen);
|
||||
unsigned status_flags, char *result, unsigned maxlen);
|
||||
|
||||
typedef int (*dm_message_fn) (struct dm_target *ti, unsigned argc, char **argv);
|
||||
|
||||
|
|
|
@ -267,9 +267,9 @@ enum {
|
|||
#define DM_DEV_SET_GEOMETRY _IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl)
|
||||
|
||||
#define DM_VERSION_MAJOR 4
|
||||
#define DM_VERSION_MINOR 22
|
||||
#define DM_VERSION_PATCHLEVEL 1
|
||||
#define DM_VERSION_EXTRA "-ioctl (2012-06-01)"
|
||||
#define DM_VERSION_MINOR 23
|
||||
#define DM_VERSION_PATCHLEVEL 0
|
||||
#define DM_VERSION_EXTRA "-ioctl (2012-07-25)"
|
||||
|
||||
/* Status bits */
|
||||
#define DM_READONLY_FLAG (1 << 0) /* In/Out */
|
||||
|
@ -307,6 +307,8 @@ enum {
|
|||
|
||||
/*
|
||||
* Set this to suspend without flushing queued ios.
|
||||
* Also disables flushing uncommitted changes in the thin target before
|
||||
* generating statistics for DM_TABLE_STATUS and DM_DEV_WAIT.
|
||||
*/
|
||||
#define DM_NOFLUSH_FLAG (1 << 11) /* In */
|
||||
|
||||
|
|
Loading…
Reference in a new issue