aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/dm-snap.c52
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
975static 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)
983static struct dm_snap_pending_exception * 994static 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) {