diff options
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/dm-snap.c | 52 |
1 files changed, 28 insertions, 24 deletions
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index 65ff82ff124e..87a2803ba6bd 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c | |||
@@ -972,6 +972,17 @@ static void start_copy(struct dm_snap_pending_exception *pe) | |||
972 | &src, 1, &dest, 0, copy_callback, pe); | 972 | &src, 1, &dest, 0, copy_callback, pe); |
973 | } | 973 | } |
974 | 974 | ||
975 | static struct dm_snap_pending_exception * | ||
976 | __lookup_pending_exception(struct dm_snapshot *s, chunk_t chunk) | ||
977 | { | ||
978 | struct dm_snap_exception *e = lookup_exception(&s->pending, chunk); | ||
979 | |||
980 | if (!e) | ||
981 | return NULL; | ||
982 | |||
983 | return container_of(e, struct dm_snap_pending_exception, e); | ||
984 | } | ||
985 | |||
975 | /* | 986 | /* |
976 | * Looks to see if this snapshot already has a pending exception | 987 | * Looks to see if this snapshot already has a pending exception |
977 | * for this chunk, otherwise it allocates a new one and inserts | 988 | * for this chunk, otherwise it allocates a new one and inserts |
@@ -983,21 +994,10 @@ static void start_copy(struct dm_snap_pending_exception *pe) | |||
983 | static struct dm_snap_pending_exception * | 994 | static struct dm_snap_pending_exception * |
984 | __find_pending_exception(struct dm_snapshot *s, struct bio *bio) | 995 | __find_pending_exception(struct dm_snapshot *s, struct bio *bio) |
985 | { | 996 | { |
986 | struct dm_snap_exception *e; | 997 | struct dm_snap_pending_exception *pe, *pe2; |
987 | struct dm_snap_pending_exception *pe; | ||
988 | chunk_t chunk = sector_to_chunk(s, bio->bi_sector); | 998 | chunk_t chunk = sector_to_chunk(s, bio->bi_sector); |
989 | 999 | ||
990 | /* | 1000 | /* |
991 | * Is there a pending exception for this already ? | ||
992 | */ | ||
993 | e = lookup_exception(&s->pending, chunk); | ||
994 | if (e) { | ||
995 | /* cast the exception to a pending exception */ | ||
996 | pe = container_of(e, struct dm_snap_pending_exception, e); | ||
997 | goto out; | ||
998 | } | ||
999 | |||
1000 | /* | ||
1001 | * Create a new pending exception, we don't want | 1001 | * Create a new pending exception, we don't want |
1002 | * to hold the lock while we do this. | 1002 | * to hold the lock while we do this. |
1003 | */ | 1003 | */ |
@@ -1010,11 +1010,10 @@ __find_pending_exception(struct dm_snapshot *s, struct bio *bio) | |||
1010 | return NULL; | 1010 | return NULL; |
1011 | } | 1011 | } |
1012 | 1012 | ||
1013 | e = lookup_exception(&s->pending, chunk); | 1013 | pe2 = __lookup_pending_exception(s, chunk); |
1014 | if (e) { | 1014 | if (pe2) { |
1015 | free_pending_exception(pe); | 1015 | free_pending_exception(pe); |
1016 | pe = container_of(e, struct dm_snap_pending_exception, e); | 1016 | return pe2; |
1017 | goto out; | ||
1018 | } | 1017 | } |
1019 | 1018 | ||
1020 | pe->e.old_chunk = chunk; | 1019 | pe->e.old_chunk = chunk; |
@@ -1032,7 +1031,6 @@ __find_pending_exception(struct dm_snapshot *s, struct bio *bio) | |||
1032 | get_pending_exception(pe); | 1031 | get_pending_exception(pe); |
1033 | insert_exception(&s->pending, &pe->e); | 1032 | insert_exception(&s->pending, &pe->e); |
1034 | 1033 | ||
1035 | out: | ||
1036 | return pe; | 1034 | return pe; |
1037 | } | 1035 | } |
1038 | 1036 | ||
@@ -1083,11 +1081,14 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio, | |||
1083 | * writeable. | 1081 | * writeable. |
1084 | */ | 1082 | */ |
1085 | if (bio_rw(bio) == WRITE) { | 1083 | if (bio_rw(bio) == WRITE) { |
1086 | pe = __find_pending_exception(s, bio); | 1084 | pe = __lookup_pending_exception(s, chunk); |
1087 | if (!pe) { | 1085 | if (!pe) { |
1088 | __invalidate_snapshot(s, -ENOMEM); | 1086 | pe = __find_pending_exception(s, bio); |
1089 | r = -EIO; | 1087 | if (!pe) { |
1090 | goto out_unlock; | 1088 | __invalidate_snapshot(s, -ENOMEM); |
1089 | r = -EIO; | ||
1090 | goto out_unlock; | ||
1091 | } | ||
1091 | } | 1092 | } |
1092 | 1093 | ||
1093 | remap_exception(s, &pe->e, bio, chunk); | 1094 | remap_exception(s, &pe->e, bio, chunk); |
@@ -1217,10 +1218,13 @@ static int __origin_write(struct list_head *snapshots, struct bio *bio) | |||
1217 | if (e) | 1218 | if (e) |
1218 | goto next_snapshot; | 1219 | goto next_snapshot; |
1219 | 1220 | ||
1220 | pe = __find_pending_exception(snap, bio); | 1221 | pe = __lookup_pending_exception(snap, chunk); |
1221 | if (!pe) { | 1222 | if (!pe) { |
1222 | __invalidate_snapshot(snap, -ENOMEM); | 1223 | pe = __find_pending_exception(snap, bio); |
1223 | goto next_snapshot; | 1224 | if (!pe) { |
1225 | __invalidate_snapshot(snap, -ENOMEM); | ||
1226 | goto next_snapshot; | ||
1227 | } | ||
1224 | } | 1228 | } |
1225 | 1229 | ||
1226 | if (!primary_pe) { | 1230 | if (!primary_pe) { |