1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00

Add dm_tree_use_no_flush_suspend().

This commit is contained in:
Alasdair Kergon 2007-01-09 19:44:07 +00:00
parent 616c3eccfd
commit b9ffd32cd3
4 changed files with 29 additions and 4 deletions

View File

@ -1,5 +1,6 @@
Version 1.02.14 -
=============================
Add dm_tree_use_no_flush_suspend().
Lots of dmevent changes.
Export dm_basename().
Cope with a trailing space when comparing tables prior to possible reload.

View File

@ -66,6 +66,7 @@ dm_tree_node_add_mirror_target
dm_tree_node_add_mirror_target_log
dm_tree_node_add_target_area
dm_tree_skip_lockfs
dm_tree_use_no_flush_suspend
dm_is_dm_major
dm_mknodes
dm_malloc_aux

View File

@ -315,6 +315,16 @@ int dm_tree_suspend_children(struct dm_tree_node *dnode,
*/
void dm_tree_skip_lockfs(struct dm_tree_node *dnode);
/*
* Set the 'noflush' flag when suspending devices.
* If the kernel supports it, instead of erroring outstanding I/O that
* cannot be completed, the I/O is queued and resubmitted when the
* device is resumed. This affects multipath devices when all paths
* have failed and queue_if_no_path is set, and mirror devices when
* block_on_error is set and the mirror log has failed.
*/
void dm_tree_use_no_flush_suspend(struct dm_tree_node *dnode);
/*
* Is the uuid prefix present in the tree?
* Only returns 0 if every node was checked successfully.

View File

@ -130,6 +130,7 @@ struct dm_tree {
struct dm_hash_table *uuids;
struct dm_tree_node root;
int skip_lockfs; /* 1 skips lockfs (for non-snapshots) */
int no_flush; /* 1 sets noflush (mirrors/multipath) */
};
/* FIXME Consider exporting this */
@ -162,6 +163,7 @@ struct dm_tree *dm_tree_create(void)
list_init(&dtree->root.uses);
list_init(&dtree->root.used_by);
dtree->skip_lockfs = 0;
dtree->no_flush = 0;
if (!(dtree->mem = dm_pool_create("dtree", 1024))) {
log_error("dtree pool creation failed");
@ -903,13 +905,15 @@ static int _resume_node(const char *name, uint32_t major, uint32_t minor,
}
static int _suspend_node(const char *name, uint32_t major, uint32_t minor,
int skip_lockfs, struct dm_info *newinfo)
int skip_lockfs, int no_flush, struct dm_info *newinfo)
{
struct dm_task *dmt;
int r;
log_verbose("Suspending %s (%" PRIu32 ":%" PRIu32 ")%s", name, major,
minor, skip_lockfs ? "" : " with filesystem sync.");
log_verbose("Suspending %s (%" PRIu32 ":%" PRIu32 ")%s%s",
name, major, minor,
skip_lockfs ? "" : " with filesystem sync",
no_flush ? "" : " without device flush");
if (!(dmt = dm_task_create(DM_DEVICE_SUSPEND))) {
log_error("Suspend dm_task creation failed for %s", name);
@ -928,6 +932,9 @@ static int _suspend_node(const char *name, uint32_t major, uint32_t minor,
if (skip_lockfs && !dm_task_skip_lockfs(dmt))
log_error("Failed to set skip_lockfs flag.");
if (no_flush && !dm_task_no_flush(dmt))
log_error("Failed to set no_flush flag.");
if ((r = dm_task_run(dmt)))
r = dm_task_get_info(dmt, newinfo);
@ -991,6 +998,11 @@ void dm_tree_skip_lockfs(struct dm_tree_node *dnode)
dnode->dtree->skip_lockfs = 1;
}
void dm_tree_use_no_flush_suspend(struct dm_tree_node *dnode)
{
dnode->dtree->no_flush = 1;
}
int dm_tree_suspend_children(struct dm_tree_node *dnode,
const char *uuid_prefix,
size_t uuid_prefix_len)
@ -1032,7 +1044,8 @@ int dm_tree_suspend_children(struct dm_tree_node *dnode,
continue;
if (!_suspend_node(name, info.major, info.minor,
child->dtree->skip_lockfs, &newinfo)) {
child->dtree->skip_lockfs,
child->dtree->no_flush, &newinfo)) {
log_error("Unable to suspend %s (%" PRIu32
":%" PRIu32 ")", name, info.major,
info.minor);