diff options
author | Alasdair G Kergon <agk@redhat.com> | 2012-07-27 10:08:16 -0400 |
---|---|---|
committer | Alasdair G Kergon <agk@redhat.com> | 2012-07-27 10:08:16 -0400 |
commit | 1f4e0ff07980820977f45d6a5dbc81d3bb9ce4d3 (patch) | |
tree | 5b5a159add010d09ea58ca12fd079b16f05333b8 /drivers/md | |
parent | e49e582965b3694f07a106adc83ddb44aa4f0890 (diff) |
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, | |||
1733 | } | 1733 | } |
1734 | 1734 | ||
1735 | static int crypt_status(struct dm_target *ti, status_type_t type, | 1735 | static int crypt_status(struct dm_target *ti, status_type_t type, |
1736 | char *result, unsigned int maxlen) | 1736 | unsigned status_flags, char *result, unsigned maxlen) |
1737 | { | 1737 | { |
1738 | struct crypt_config *cc = ti->private; | 1738 | struct crypt_config *cc = ti->private; |
1739 | unsigned int sz = 0; | 1739 | 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, | |||
295 | } | 295 | } |
296 | 296 | ||
297 | static int delay_status(struct dm_target *ti, status_type_t type, | 297 | static int delay_status(struct dm_target *ti, status_type_t type, |
298 | char *result, unsigned maxlen) | 298 | unsigned status_flags, char *result, unsigned maxlen) |
299 | { | 299 | { |
300 | struct delay_c *dc = ti->private; | 300 | struct delay_c *dc = ti->private; |
301 | int sz = 0; | 301 | 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, | |||
333 | } | 333 | } |
334 | 334 | ||
335 | static int flakey_status(struct dm_target *ti, status_type_t type, | 335 | static int flakey_status(struct dm_target *ti, status_type_t type, |
336 | char *result, unsigned int maxlen) | 336 | unsigned status_flags, char *result, unsigned maxlen) |
337 | { | 337 | { |
338 | unsigned sz = 0; | 338 | unsigned sz = 0; |
339 | struct flakey_c *fc = ti->private; | 339 | 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, | |||
1054 | char *outbuf, *outptr; | 1054 | char *outbuf, *outptr; |
1055 | status_type_t type; | 1055 | status_type_t type; |
1056 | size_t remaining, len, used = 0; | 1056 | size_t remaining, len, used = 0; |
1057 | unsigned status_flags = 0; | ||
1057 | 1058 | ||
1058 | outptr = outbuf = get_result_buffer(param, param_size, &len); | 1059 | outptr = outbuf = get_result_buffer(param, param_size, &len); |
1059 | 1060 | ||
@@ -1090,7 +1091,9 @@ static void retrieve_status(struct dm_table *table, | |||
1090 | 1091 | ||
1091 | /* Get the status/table string from the target driver */ | 1092 | /* Get the status/table string from the target driver */ |
1092 | if (ti->type->status) { | 1093 | if (ti->type->status) { |
1093 | if (ti->type->status(ti, type, outptr, remaining)) { | 1094 | if (param->flags & DM_NOFLUSH_FLAG) |
1095 | status_flags |= DM_STATUS_NOFLUSH_FLAG; | ||
1096 | if (ti->type->status(ti, type, status_flags, outptr, remaining)) { | ||
1094 | param->flags |= DM_BUFFER_FULL_FLAG; | 1097 | param->flags |= DM_BUFFER_FULL_FLAG; |
1095 | break; | 1098 | break; |
1096 | } | 1099 | } |
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, | |||
96 | } | 96 | } |
97 | 97 | ||
98 | static int linear_status(struct dm_target *ti, status_type_t type, | 98 | static int linear_status(struct dm_target *ti, status_type_t type, |
99 | char *result, unsigned int maxlen) | 99 | unsigned status_flags, char *result, unsigned maxlen) |
100 | { | 100 | { |
101 | struct linear_c *lc = (struct linear_c *) ti->private; | 101 | struct linear_c *lc = (struct linear_c *) ti->private; |
102 | 102 | ||
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) | |||
1378 | * num_paths num_selector_args [path_dev [selector_args]* ]+ ]+ | 1378 | * num_paths num_selector_args [path_dev [selector_args]* ]+ ]+ |
1379 | */ | 1379 | */ |
1380 | static int multipath_status(struct dm_target *ti, status_type_t type, | 1380 | static int multipath_status(struct dm_target *ti, status_type_t type, |
1381 | char *result, unsigned int maxlen) | 1381 | unsigned status_flags, char *result, unsigned maxlen) |
1382 | { | 1382 | { |
1383 | int sz = 0; | 1383 | int sz = 0; |
1384 | unsigned long flags; | 1384 | 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 | |||
1081 | } | 1081 | } |
1082 | 1082 | ||
1083 | static int raid_status(struct dm_target *ti, status_type_t type, | 1083 | static int raid_status(struct dm_target *ti, status_type_t type, |
1084 | char *result, unsigned maxlen) | 1084 | unsigned status_flags, char *result, unsigned maxlen) |
1085 | { | 1085 | { |
1086 | struct raid_set *rs = ti->private; | 1086 | struct raid_set *rs = ti->private; |
1087 | unsigned raid_param_cnt = 1; /* at least 1 for chunksize */ | 1087 | 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) | |||
1367 | 1367 | ||
1368 | 1368 | ||
1369 | static int mirror_status(struct dm_target *ti, status_type_t type, | 1369 | static int mirror_status(struct dm_target *ti, status_type_t type, |
1370 | char *result, unsigned int maxlen) | 1370 | unsigned status_flags, char *result, unsigned maxlen) |
1371 | { | 1371 | { |
1372 | unsigned int m, sz = 0; | 1372 | unsigned int m, sz = 0; |
1373 | struct mirror_set *ms = (struct mirror_set *) ti->private; | 1373 | 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) | |||
1849 | } | 1849 | } |
1850 | 1850 | ||
1851 | static int snapshot_status(struct dm_target *ti, status_type_t type, | 1851 | static int snapshot_status(struct dm_target *ti, status_type_t type, |
1852 | char *result, unsigned int maxlen) | 1852 | unsigned status_flags, char *result, unsigned maxlen) |
1853 | { | 1853 | { |
1854 | unsigned sz = 0; | 1854 | unsigned sz = 0; |
1855 | struct dm_snapshot *snap = ti->private; | 1855 | struct dm_snapshot *snap = ti->private; |
@@ -2151,8 +2151,8 @@ static void origin_resume(struct dm_target *ti) | |||
2151 | ti->max_io_len = get_origin_minimum_chunksize(dev->bdev); | 2151 | ti->max_io_len = get_origin_minimum_chunksize(dev->bdev); |
2152 | } | 2152 | } |
2153 | 2153 | ||
2154 | static int origin_status(struct dm_target *ti, status_type_t type, char *result, | 2154 | static int origin_status(struct dm_target *ti, status_type_t type, |
2155 | unsigned int maxlen) | 2155 | unsigned status_flags, char *result, unsigned maxlen) |
2156 | { | 2156 | { |
2157 | struct dm_dev *dev = ti->private; | 2157 | struct dm_dev *dev = ti->private; |
2158 | 2158 | ||
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, | |||
311 | * | 311 | * |
312 | */ | 312 | */ |
313 | 313 | ||
314 | static int stripe_status(struct dm_target *ti, | 314 | static int stripe_status(struct dm_target *ti, status_type_t type, |
315 | status_type_t type, char *result, unsigned int maxlen) | 315 | unsigned status_flags, char *result, unsigned maxlen) |
316 | { | 316 | { |
317 | struct stripe_c *sc = (struct stripe_c *) ti->private; | 317 | struct stripe_c *sc = (struct stripe_c *) ti->private; |
318 | char buffer[sc->stripes + 1]; | 318 | 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 @@ | |||
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include "dm-thin-metadata.h" | 7 | #include "dm-thin-metadata.h" |
8 | #include "dm.h" | ||
8 | 9 | ||
9 | #include <linux/device-mapper.h> | 10 | #include <linux/device-mapper.h> |
10 | #include <linux/dm-io.h> | 11 | #include <linux/dm-io.h> |
@@ -2619,7 +2620,7 @@ static void emit_flags(struct pool_features *pf, char *result, | |||
2619 | * <used data sectors>/<total data sectors> <held metadata root> | 2620 | * <used data sectors>/<total data sectors> <held metadata root> |
2620 | */ | 2621 | */ |
2621 | static int pool_status(struct dm_target *ti, status_type_t type, | 2622 | static int pool_status(struct dm_target *ti, status_type_t type, |
2622 | char *result, unsigned maxlen) | 2623 | unsigned status_flags, char *result, unsigned maxlen) |
2623 | { | 2624 | { |
2624 | int r; | 2625 | int r; |
2625 | unsigned sz = 0; | 2626 | unsigned sz = 0; |
@@ -2641,6 +2642,10 @@ static int pool_status(struct dm_target *ti, status_type_t type, | |||
2641 | break; | 2642 | break; |
2642 | } | 2643 | } |
2643 | 2644 | ||
2645 | /* Commit to ensure statistics aren't out-of-date */ | ||
2646 | if (!(status_flags & DM_STATUS_NOFLUSH_FLAG) && !dm_suspended(ti)) | ||
2647 | (void) commit_or_fallback(pool); | ||
2648 | |||
2644 | r = dm_pool_get_metadata_transaction_id(pool->pmd, | 2649 | r = dm_pool_get_metadata_transaction_id(pool->pmd, |
2645 | &transaction_id); | 2650 | &transaction_id); |
2646 | if (r) | 2651 | if (r) |
@@ -2968,7 +2973,7 @@ static void thin_postsuspend(struct dm_target *ti) | |||
2968 | * <nr mapped sectors> <highest mapped sector> | 2973 | * <nr mapped sectors> <highest mapped sector> |
2969 | */ | 2974 | */ |
2970 | static int thin_status(struct dm_target *ti, status_type_t type, | 2975 | static int thin_status(struct dm_target *ti, status_type_t type, |
2971 | char *result, unsigned maxlen) | 2976 | unsigned status_flags, char *result, unsigned maxlen) |
2972 | { | 2977 | { |
2973 | int r; | 2978 | int r; |
2974 | ssize_t sz = 0; | 2979 | 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, | |||
515 | * Status: V (valid) or C (corruption found) | 515 | * Status: V (valid) or C (corruption found) |
516 | */ | 516 | */ |
517 | static int verity_status(struct dm_target *ti, status_type_t type, | 517 | static int verity_status(struct dm_target *ti, status_type_t type, |
518 | char *result, unsigned maxlen) | 518 | unsigned status_flags, char *result, unsigned maxlen) |
519 | { | 519 | { |
520 | struct dm_verity *v = ti->private; | 520 | struct dm_verity *v = ti->private; |
521 | unsigned sz = 0; | 521 | 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 @@ | |||
23 | #define DM_SUSPEND_NOFLUSH_FLAG (1 << 1) | 23 | #define DM_SUSPEND_NOFLUSH_FLAG (1 << 1) |
24 | 24 | ||
25 | /* | 25 | /* |
26 | * Status feature flags | ||
27 | */ | ||
28 | #define DM_STATUS_NOFLUSH_FLAG (1 << 0) | ||
29 | |||
30 | /* | ||
26 | * Type of table and mapped_device's mempool | 31 | * Type of table and mapped_device's mempool |
27 | */ | 32 | */ |
28 | #define DM_TYPE_NONE 0 | 33 | #define DM_TYPE_NONE 0 |