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

Added dm_tree_node_set_callback() for preload and deactivation hooks

Run users hook after preload for the node is finished,
or after the node has been deactivated.
This commit is contained in:
Zdenek Kabelac 2012-03-02 17:31:21 +00:00
parent 1babf24949
commit 7e35dfff3d
3 changed files with 41 additions and 1 deletions

View File

@ -1,5 +1,6 @@
Version 1.02.73 - Version 1.02.73 -
==================================== ====================================
Added dm_tree_node_set_callback() for preload and deactivation hooks.
Drop unsupported TRIM message for thin pool. Drop unsupported TRIM message for thin pool.
Improve logging for fifo startup in dmeventd. Improve logging for fifo startup in dmeventd.
Add few pointer validation in dmsetup. Add few pointer validation in dmsetup.

View File

@ -688,6 +688,20 @@ void dm_tree_node_set_read_ahead(struct dm_tree_node *dnode,
uint32_t read_ahead, uint32_t read_ahead,
uint32_t read_ahead_flags); uint32_t read_ahead_flags);
/*
* Set node callback hook before de/activation.
* Callback is called before 'activation' of node for activation tree,
* or 'deactivation' of node for deactivation tree.
*/
typedef enum {
DM_NODE_CALLBACK_PRELOADED, /* Node has preload deps */
DM_NODE_CALLBACK_DEACTIVATED, /* Node is deactivated */
} dm_node_callback_t;
typedef int (*dm_node_callback_fn) (struct dm_tree_node *node,
dm_node_callback_t type, void *cb_data);
void dm_tree_node_set_callback(struct dm_tree_node *node,
dm_node_callback_fn cb, void *cb_data);
void dm_tree_set_cookie(struct dm_tree_node *node, uint32_t cookie); void dm_tree_set_cookie(struct dm_tree_node *node, uint32_t cookie);
uint32_t dm_tree_get_cookie(struct dm_tree_node *node); uint32_t dm_tree_get_cookie(struct dm_tree_node *node);

View File

@ -263,6 +263,10 @@ struct dm_tree_node {
* Note: only direct child is allowed * Note: only direct child is allowed
*/ */
struct dm_tree_node *presuspend_node; struct dm_tree_node *presuspend_node;
/* Callback */
dm_node_callback_fn callback;
void *callback_data;
}; };
struct dm_tree { struct dm_tree {
@ -1588,6 +1592,14 @@ static int _dm_tree_deactivate_children(struct dm_tree_node *dnode,
} else if (info.suspended) } else if (info.suspended)
dec_suspended(); dec_suspended();
if (child->callback &&
!child->callback(child, DM_NODE_CALLBACK_DEACTIVATED,
child->callback_data)) {
r = 0;
// FIXME: break tree shutdown or continue?
// hmm what about _node_clear_table()?
}
if (dm_tree_node_num_children(child, 0)) { if (dm_tree_node_num_children(child, 0)) {
if (!_dm_tree_deactivate_children(child, uuid_prefix, uuid_prefix_len, level + 1)) if (!_dm_tree_deactivate_children(child, uuid_prefix, uuid_prefix_len, level + 1))
return_0; return_0;
@ -2445,10 +2457,16 @@ int dm_tree_preload_children(struct dm_tree_node *dnode,
update_devs_flag = 1; update_devs_flag = 1;
} }
if (update_devs_flag) { if (update_devs_flag ||
(!dnode->info.exists && dnode->callback)) {
if (!dm_udev_wait(dm_tree_get_cookie(dnode))) if (!dm_udev_wait(dm_tree_get_cookie(dnode)))
stack; stack;
dm_tree_set_cookie(dnode, 0); dm_tree_set_cookie(dnode, 0);
if (!dnode->info.exists && dnode->callback &&
!dnode->callback(child, DM_NODE_CALLBACK_PRELOADED,
dnode->callback_data))
return_0;
} }
return r; return r;
@ -3245,3 +3263,10 @@ int dm_tree_node_add_null_area(struct dm_tree_node *node, uint64_t offset)
return 1; return 1;
} }
void dm_tree_node_set_callback(struct dm_tree_node *dnode,
dm_node_callback_fn cb, void *data)
{
dnode->callback = cb;
dnode->callback_data = data;
}