The DM thin-pool target now must undo the changes performed during pool_presuspend() so introduce presuspend_undo hook in target_type.
Unified · Split
| @@ -1521,18 +1521,32 @@ fmode_t dm_table_get_mode(struct dm_table *t) · 1520 unmodified lines | ||
| 1521 | 1521 | } |
| 1522 | 1522 | EXPORT_SYMBOL(dm_table_get_mode); |
| 1523 | 1523 | |
| 1524 | −static void suspend_targets(struct dm_table *t, unsigned postsuspend) | |
| 1524 | +enum suspend_mode { | |
| 1525 | + PRESUSPEND, | |
| 1526 | + PRESUSPEND_UNDO, | |
| 1527 | + POSTSUSPEND, | |
| 1528 | +}; | |
| 1529 | + | |
| 1530 | +static void suspend_targets(struct dm_table *t, enum suspend_mode mode) | |
| 1525 | 1531 | { |
| 1526 | 1532 | int i = t->num_targets; |
| 1527 | 1533 | struct dm_target *ti = t->targets; |
| 1528 | 1534 | |
| 1529 | 1535 | while (i--) { |
| 1530 | − if (postsuspend) { | |
| 1536 | + switch (mode) { | |
| 1537 | + case PRESUSPEND: | |
| 1538 | + if (ti->type->presuspend) | |
| 1539 | + ti->type->presuspend(ti); | |
| 1540 | + break; | |
| 1541 | + case PRESUSPEND_UNDO: | |
| 1542 | + if (ti->type->presuspend_undo) | |
| 1543 | + ti->type->presuspend_undo(ti); | |
| 1544 | + break; | |
| 1545 | + case POSTSUSPEND: | |
| 1531 | 1546 | if (ti->type->postsuspend) |
| 1532 | 1547 | ti->type->postsuspend(ti); |
| 1533 | − } else if (ti->type->presuspend) | |
| 1534 | − ti->type->presuspend(ti); | |
| 1535 | − | |
| 1548 | + break; | |
| 1549 | + } | |
| 1536 | 1550 | ti++; |
| 1537 | 1551 | } |
| 1538 | 1552 | } |
| @@ -1542,7 +1556,15 @@ void dm_table_presuspend_targets(struct dm_table *t) · 3 unmodified lines | ||
| 1542 | 1556 | if (!t) |
| 1543 | 1557 | return; |
| 1544 | 1558 | |
| 1545 | − suspend_targets(t, 0); | |
| 1559 | + suspend_targets(t, PRESUSPEND); | |
| 1560 | +} | |
| 1561 | + | |
| 1562 | +void dm_table_presuspend_undo_targets(struct dm_table *t) | |
| 1563 | +{ | |
| 1564 | + if (!t) | |
| 1565 | + return; | |
| 1566 | + | |
| 1567 | + suspend_targets(t, PRESUSPEND_UNDO); | |
| 1546 | 1568 | } |
| 1547 | 1569 | |
| 1548 | 1570 | void dm_table_postsuspend_targets(struct dm_table *t) |
| @@ -1550,7 +1572,7 @@ void dm_table_postsuspend_targets(struct dm_table *t) · 1 unmodified line | ||
| 1550 | 1572 | if (!t) |
| 1551 | 1573 | return; |
| 1552 | 1574 | |
| 1553 | − suspend_targets(t, 1); | |
| 1575 | + suspend_targets(t, POSTSUSPEND); | |
| 1554 | 1576 | } |
| 1555 | 1577 | |
| 1556 | 1578 | int dm_table_resume_targets(struct dm_table *t) |
| @@ -2756,7 +2756,10 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) · 2755 unmodified lines | ||
| 2756 | 2756 | if (noflush) |
| 2757 | 2757 | set_bit(DMF_NOFLUSH_SUSPENDING, &md->flags); |
| 2758 | 2758 | |
| 2759 | − /* This does not get reverted if there's an error later. */ | |
| 2759 | + /* | |
| 2760 | + * This gets reverted if there's an error later and the targets | |
| 2761 | + * provide the .presuspend_undo hook. | |
| 2762 | + */ | |
| 2760 | 2763 | dm_table_presuspend_targets(map); |
| 2761 | 2764 | |
| 2762 | 2765 | /* |
| @@ -2767,8 +2770,10 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) · 4 unmodified lines | ||
| 2767 | 2770 | */ |
| 2768 | 2771 | if (!noflush && do_lockfs) { |
| 2769 | 2772 | r = lock_fs(md); |
| 2770 | − if (r) | |
| 2773 | + if (r) { | |
| 2774 | + dm_table_presuspend_undo_targets(map); | |
| 2771 | 2775 | goto out_unlock; |
| 2776 | + } | |
| 2772 | 2777 | } |
| 2773 | 2778 | |
| 2774 | 2779 | /* |
| @@ -2816,6 +2821,7 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) · 41 unmodified lines | ||
| 2816 | 2821 | start_queue(md->queue); |
| 2817 | 2822 | |
| 2818 | 2823 | unlock_fs(md); |
| 2824 | + dm_table_presuspend_undo_targets(map); | |
| 2819 | 2825 | goto out_unlock; /* pushback list is already flushed, so skip flush */ |
| 2820 | 2826 | } |
| 2821 | 2827 | |
| @@ -65,6 +65,7 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q, · 64 unmodified lines | ||
| 65 | 65 | struct queue_limits *limits); |
| 66 | 66 | struct list_head *dm_table_get_devices(struct dm_table *t); |
| 67 | 67 | void dm_table_presuspend_targets(struct dm_table *t); |
| 68 | +void dm_table_presuspend_undo_targets(struct dm_table *t); | |
| 68 | 69 | void dm_table_postsuspend_targets(struct dm_table *t); |
| 69 | 70 | int dm_table_resume_targets(struct dm_table *t); |
| 70 | 71 | int dm_table_any_congested(struct dm_table *t, int bdi_bits); |
| @@ -64,6 +64,7 @@ typedef int (*dm_request_endio_fn) (struct dm_target *ti, · 63 unmodified lines | ||
| 64 | 64 | union map_info *map_context); |
| 65 | 65 | |
| 66 | 66 | typedef void (*dm_presuspend_fn) (struct dm_target *ti); |
| 67 | +typedef void (*dm_presuspend_undo_fn) (struct dm_target *ti); | |
| 67 | 68 | typedef void (*dm_postsuspend_fn) (struct dm_target *ti); |
| 68 | 69 | typedef int (*dm_preresume_fn) (struct dm_target *ti); |
| 69 | 70 | typedef void (*dm_resume_fn) (struct dm_target *ti); |
| @@ -145,6 +146,7 @@ struct target_type { · 75 unmodified lines | ||
| 145 | 146 | dm_endio_fn end_io; |
| 146 | 147 | dm_request_endio_fn rq_end_io; |
| 147 | 148 | dm_presuspend_fn presuspend; |
| 149 | + dm_presuspend_undo_fn presuspend_undo; | |
| 148 | 150 | dm_postsuspend_fn postsuspend; |
| 149 | 151 | dm_preresume_fn preresume; |
| 150 | 152 | dm_resume_fn resume; |
| @@ -267,9 +267,9 @@ enum { · 266 unmodified lines | ||
| 267 | 267 | #define DM_DEV_SET_GEOMETRY _IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl) |
| 268 | 268 | |
| 269 | 269 | #define DM_VERSION_MAJOR 4 |
| 270 | −#define DM_VERSION_MINOR 28 | |
| 270 | +#define DM_VERSION_MINOR 29 | |
| 271 | 271 | #define DM_VERSION_PATCHLEVEL 0 |
| 272 | −#define DM_VERSION_EXTRA "-ioctl (2014-09-17)" | |
| 272 | +#define DM_VERSION_EXTRA "-ioctl (2014-10-28)" | |
| 273 | 273 | |
| 274 | 274 | /* Status bits */ |
| 275 | 275 | #define DM_READONLY_FLAG (1 << 0) /* In/Out */ |