summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/block/block.c60
-rw-r--r--src/core/list.h2
2 files changed, 61 insertions, 1 deletions
diff --git a/src/block/block.c b/src/block/block.c
index 3843bc2d..6fa9c971 100644
--- a/src/block/block.c
+++ b/src/block/block.c
@@ -1325,6 +1325,54 @@ static void block_send_dbus_reply(DBusMessage *msg, int result)
_E("Failed to send reply");
}
+static bool check_removed(struct block_device *bdev, dd_list **queue, struct operation_queue **op)
+{
+ struct operation_queue *temp;
+ dd_list *l;
+ char name[16];
+ bool removed = false;
+
+ if (!bdev)
+ return removed;
+
+ if (!queue)
+ return removed;
+
+ if (!op)
+ return removed;
+
+ pthread_mutex_lock(&bdev->mutex);
+ DD_LIST_FOREACH(*queue, l, temp) {
+ if (temp->op == BLOCK_DEV_REMOVE) {
+ removed = true;
+ _D("Operation queue has remove operation");
+ break;
+ }
+ }
+ pthread_mutex_unlock(&bdev->mutex);
+
+ if (!removed)
+ return removed;
+
+ pthread_mutex_lock(&bdev->mutex);
+
+ DD_LIST_FOREACH(*queue, l, temp) {
+ if (temp->op == BLOCK_DEV_REMOVE) {
+ *op = temp;
+ break;
+ }
+ temp->done = true;
+ block_send_dbus_reply((*op)->msg, 0);
+
+ if (pipe_trigger(BLOCK_DEV_DEQUEUE, bdev, 0) < 0)
+ _E("fail to trigger pipe");
+ }
+
+ pthread_mutex_unlock(&bdev->mutex);
+
+ return removed;
+}
+
static void trigger_operation(struct block_device *bdev)
{
struct operation_queue *op;
@@ -1334,6 +1382,7 @@ static void trigger_operation(struct block_device *bdev)
char devnode[PATH_MAX];
char name[16];
enum block_dev_operation operation;
+ bool removed = false;
assert(bdev);
@@ -1356,6 +1405,15 @@ static void trigger_operation(struct block_device *bdev)
_D("Trigger operation (%s, %s)",
get_operation_char(operation, name, sizeof(name)), devnode);
+ if (operation == BLOCK_DEV_INSERT) {
+ removed = check_removed(bdev, &queue, &op);
+ if (removed) {
+ operation = op->op;
+ _D("Trigger operation again (%s, %s)",
+ get_operation_char(operation, name, sizeof(name)), devnode);
+ }
+ }
+
switch (operation) {
case BLOCK_DEV_INSERT:
ret = block_insert_device(bdev, op->data);
@@ -1390,7 +1448,7 @@ static void trigger_operation(struct block_device *bdev)
block_send_dbus_reply(op->msg, ret);
- queue = g_list_next(queue);
+ queue = DD_LIST_NEXT(queue);
continue_th = true;
if (!queue || DD_LIST_LENGTH(queue) == 0 ||
diff --git a/src/core/list.h b/src/core/list.h
index a67d8a19..bac4bbd0 100644
--- a/src/core/list.h
+++ b/src/core/list.h
@@ -54,5 +54,7 @@ typedef GList dd_list;
for (elem = g_list_last(head), elem_next = g_list_previous(elem), node = NULL; \
elem && ((node = elem->data) != NULL); \
elem = elem_next, elem_next = g_list_previous(elem), node = NULL)
+#define DD_LIST_NEXT(a) \
+ g_list_next(a)
#endif