diff options
| author | Alasdair G Kergon <agk@redhat.com> | 2012-07-27 15:08:16 +0100 | 
|---|---|---|
| committer | Alasdair G Kergon <agk@redhat.com> | 2012-07-27 15:08:16 +0100 | 
| commit | 1f4e0ff07980820977f45d6a5dbc81d3bb9ce4d3 (patch) | |
| tree | 5b5a159add010d09ea58ca12fd079b16f05333b8 /drivers/md | |
| parent | e49e582965b3694f07a106adc83ddb44aa4f0890 (diff) | |
| download | linux-1f4e0ff07980820977f45d6a5dbc81d3bb9ce4d3.tar.bz2 | |
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>
Diffstat (limited to 'drivers/md')
| -rw-r--r-- | drivers/md/dm-crypt.c | 2 | ||||
| -rw-r--r-- | drivers/md/dm-delay.c | 2 | ||||
| -rw-r--r-- | drivers/md/dm-flakey.c | 2 | ||||
| -rw-r--r-- | drivers/md/dm-ioctl.c | 5 | ||||
| -rw-r--r-- | drivers/md/dm-linear.c | 2 | ||||
| -rw-r--r-- | drivers/md/dm-mpath.c | 2 | ||||
| -rw-r--r-- | drivers/md/dm-raid.c | 2 | ||||
| -rw-r--r-- | drivers/md/dm-raid1.c | 2 | ||||
| -rw-r--r-- | drivers/md/dm-snap.c | 6 | ||||
| -rw-r--r-- | drivers/md/dm-stripe.c | 4 | ||||
| -rw-r--r-- | drivers/md/dm-thin.c | 9 | ||||
| -rw-r--r-- | drivers/md/dm-verity.c | 2 | ||||
| -rw-r--r-- | drivers/md/dm.h | 5 | 
13 files changed, 29 insertions, 16 deletions
| diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 00a25ab987c9..664743d6a6cd 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -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; diff --git a/drivers/md/dm-delay.c b/drivers/md/dm-delay.c index 2dc22dddb2ae..f53846f9ab50 100644 --- a/drivers/md/dm-delay.c +++ b/drivers/md/dm-delay.c @@ -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; diff --git a/drivers/md/dm-flakey.c b/drivers/md/dm-flakey.c index ac49c01f1a44..cc15543a6ad7 100644 --- a/drivers/md/dm-flakey.c +++ b/drivers/md/dm-flakey.c @@ -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; diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c index a1a3e6df17b8..afd95986d099 100644 --- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c @@ -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;  			} diff --git a/drivers/md/dm-linear.c b/drivers/md/dm-linear.c index 3639eeab6042..1bf19a93eef0 100644 --- a/drivers/md/dm-linear.c +++ b/drivers/md/dm-linear.c @@ -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; diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index 8a3b2d53f81b..d8abb90a6c2f 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c @@ -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; diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c index f4275a8e860c..f2f29c526544 100644 --- a/drivers/md/dm-raid.c +++ b/drivers/md/dm-raid.c @@ -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 */ diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 596a3a1164a7..bc5ddba8045b 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c @@ -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; diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index 6c0f3e33923a..a143921feaf6 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -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; diff --git a/drivers/md/dm-stripe.c b/drivers/md/dm-stripe.c index 9e8f4cc63d6c..a087bf2a8d66 100644 --- a/drivers/md/dm-stripe.c +++ b/drivers/md/dm-stripe.c @@ -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]; diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c index 087e9b34d290..af1fc3b2c2ad 100644 --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c @@ -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; diff --git a/drivers/md/dm-verity.c b/drivers/md/dm-verity.c index fa365d39b612..254d19268ad2 100644 --- a/drivers/md/dm-verity.c +++ b/drivers/md/dm-verity.c @@ -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; diff --git a/drivers/md/dm.h b/drivers/md/dm.h index b7dacd59d8d7..52eef493d266 100644 --- a/drivers/md/dm.h +++ b/drivers/md/dm.h @@ -23,6 +23,11 @@  #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   */  #define DM_TYPE_NONE		0 |