@@ -104,6 +104,7 @@
struct dm_mpath_io {
struct pgpath *pgpath;
size_t nr_bytes;
+ struct timer_list tmo;
};
typedef int (*action_fn) (struct pgpath *pgpath);
@@ -439,11 +440,13 @@
r = map_io(m, clone, mpio, 1);
if (r < 0) {
+ del_timer(&mpio->tmo);
mempool_free(mpio, m->mpio_pool);
dm_kill_unmapped_request(clone, r);
} else if (r == DM_MAPIO_REMAPPED)
dm_dispatch_request(clone);
else if (r == DM_MAPIO_REQUEUE) {
+ del_timer(&mpio->tmo);
mempool_free(mpio, m->mpio_pool);
dm_requeue_unmapped_request(clone);
}
@@ -940,6 +943,13 @@
free_multipath(m);
}
+static void multipath_tmo(unsigned long priv)
+{
+ struct dm_mpath_io *mpio = (struct dm_mpath_io*)priv;
+ if (mpio->pgpath)
+ fail_path(mpio->pgpath);
+}
+
/*
* Map cloned requests
*/
@@ -956,11 +966,18 @@
return DM_MAPIO_REQUEUE;
memset(mpio, 0, sizeof(*mpio));
+ init_timer(&mpio->tmo);
+ mpio->tmo.function = multipath_tmo;
+ mpio->tmo.data = (unsigned long)mpio;
+ mod_timer(&mpio->tmo, jiffies+HZ*10); // timeout should be tunable
+
map_context->ptr = mpio;
clone->cmd_flags |= REQ_FAILFAST_TRANSPORT;
r = map_io(m, clone, mpio, 0);
- if (r < 0 || r == DM_MAPIO_REQUEUE)
+ if (r < 0 || r == DM_MAPIO_REQUEUE) {
+ del_timer(&mpio->tmo);
mempool_free(mpio, m->mpio_pool);
+ }
return r;
}
@@ -1297,6 +1314,7 @@
if (ps->type->end_io)
ps->type->end_io(ps, &pgpath->path, mpio->nr_bytes);
}
+ del_timer(&mpio->tmo);
mempool_free(mpio, m->mpio_pool);
return r;