Index: uspace/srv/bd/hr/metadata/foreign/geom/hr_g_mirror.c
===================================================================
--- uspace/srv/bd/hr/metadata/foreign/geom/hr_g_mirror.c	(revision e0695cef2a4a4392f323e3f0212caa45f2b409ee)
+++ uspace/srv/bd/hr/metadata/foreign/geom/hr_g_mirror.c	(revision 6a8c1569d31b7ba25b64484de060d2f88525c8d9)
@@ -64,4 +64,5 @@
 static void meta_gmirror_inc_counter(hr_volume_t *);
 static errno_t meta_gmirror_save(hr_volume_t *, bool);
+static errno_t meta_gmirror_save_ext(hr_volume_t *, size_t, bool);
 static const char *meta_gmirror_get_devname(const void *);
 static hr_level_t meta_gmirror_get_level(const void *);
@@ -84,4 +85,5 @@
 	.inc_counter = meta_gmirror_inc_counter,
 	.save = meta_gmirror_save,
+	.save_ext = meta_gmirror_save_ext,
 	.get_devname = meta_gmirror_get_devname,
 	.get_level = meta_gmirror_get_level,
@@ -312,4 +314,12 @@
 }
 
+static errno_t meta_gmirror_save_ext(hr_volume_t *vol, size_t ext_idx,
+    bool with_state_callback)
+{
+	HR_DEBUG("%s()", __func__);
+
+	return ENOTSUP;
+}
+
 static const char *meta_gmirror_get_devname(const void *md_v)
 {
Index: uspace/srv/bd/hr/metadata/foreign/geom/hr_g_stripe.c
===================================================================
--- uspace/srv/bd/hr/metadata/foreign/geom/hr_g_stripe.c	(revision e0695cef2a4a4392f323e3f0212caa45f2b409ee)
+++ uspace/srv/bd/hr/metadata/foreign/geom/hr_g_stripe.c	(revision 6a8c1569d31b7ba25b64484de060d2f88525c8d9)
@@ -64,4 +64,5 @@
 static void meta_gstripe_inc_counter(hr_volume_t *);
 static errno_t meta_gstripe_save(hr_volume_t *, bool);
+static errno_t meta_gstripe_save_ext(hr_volume_t *, size_t, bool);
 static const char *meta_gstripe_get_devname(const void *);
 static hr_level_t meta_gstripe_get_level(const void *);
@@ -84,4 +85,5 @@
 	.inc_counter = meta_gstripe_inc_counter,
 	.save = meta_gstripe_save,
+	.save_ext = meta_gstripe_save_ext,
 	.get_devname = meta_gstripe_get_devname,
 	.get_level = meta_gstripe_get_level,
@@ -298,4 +300,12 @@
 }
 
+static errno_t meta_gstripe_save_ext(hr_volume_t *vol, size_t ext_idx,
+    bool with_state_callback)
+{
+	HR_DEBUG("%s()", __func__);
+
+	return ENOTSUP;
+}
+
 static const char *meta_gstripe_get_devname(const void *md_v)
 {
Index: uspace/srv/bd/hr/metadata/foreign/softraid/hr_softraid.c
===================================================================
--- uspace/srv/bd/hr/metadata/foreign/softraid/hr_softraid.c	(revision e0695cef2a4a4392f323e3f0212caa45f2b409ee)
+++ uspace/srv/bd/hr/metadata/foreign/softraid/hr_softraid.c	(revision 6a8c1569d31b7ba25b64484de060d2f88525c8d9)
@@ -64,4 +64,5 @@
 static void meta_softraid_inc_counter(hr_volume_t *);
 static errno_t meta_softraid_save(hr_volume_t *, bool);
+static errno_t meta_softraid_save_ext(hr_volume_t *, size_t, bool);
 static const char *meta_softraid_get_devname(const void *);
 static hr_level_t meta_softraid_get_level(const void *);
@@ -84,4 +85,5 @@
 	.inc_counter = meta_softraid_inc_counter,
 	.save = meta_softraid_save,
+	.save_ext = meta_softraid_save_ext,
 	.get_devname = meta_softraid_get_devname,
 	.get_level = meta_softraid_get_level,
@@ -437,4 +439,12 @@
 }
 
+static errno_t meta_softraid_save_ext(hr_volume_t *vol, size_t ext_idx,
+    bool with_state_callback)
+{
+	HR_DEBUG("%s()", __func__);
+
+	return ENOTSUP;
+}
+
 static const char *meta_softraid_get_devname(const void *md_v)
 {
Index: uspace/srv/bd/hr/metadata/native.c
===================================================================
--- uspace/srv/bd/hr/metadata/native.c	(revision e0695cef2a4a4392f323e3f0212caa45f2b409ee)
+++ uspace/srv/bd/hr/metadata/native.c	(revision 6a8c1569d31b7ba25b64484de060d2f88525c8d9)
@@ -65,4 +65,5 @@
 static void meta_native_inc_counter(hr_volume_t *);
 static errno_t meta_native_save(hr_volume_t *, bool);
+static errno_t meta_native_save_ext(hr_volume_t *, size_t, bool);
 static const char *meta_native_get_devname(const void *);
 static hr_level_t meta_native_get_level(const void *);
@@ -86,4 +87,5 @@
 	.inc_counter = meta_native_inc_counter,
 	.save = meta_native_save,
+	.save_ext = meta_native_save_ext,
 	.get_devname = meta_native_get_devname,
 	.get_level = meta_native_get_level,
@@ -394,5 +396,20 @@
 	HR_DEBUG("%s()", __func__);
 
-	errno_t rc = EOK;
+	fibril_rwlock_read_lock(&vol->extents_lock);
+
+	for (size_t i = 0; i < vol->extent_no; i++)
+		meta_native_save_ext(vol, i, with_state_callback);
+
+	fibril_rwlock_read_unlock(&vol->extents_lock);
+
+	return EOK;
+}
+
+static errno_t meta_native_save_ext(hr_volume_t *vol, size_t ext_idx,
+    bool with_state_callback)
+{
+	HR_DEBUG("%s()", __func__);
+
+	assert(fibril_rwlock_is_locked(&vol->extents_lock));
 
 	void *md_block = hr_calloc_waitok(1, vol->bsize);
@@ -400,35 +417,27 @@
 	hr_metadata_t *md = (hr_metadata_t *)vol->in_mem_md;
 
-	fibril_rwlock_read_lock(&vol->extents_lock);
+	hr_extent_t *ext = &vol->extents[ext_idx];
+
+	fibril_rwlock_read_lock(&vol->states_lock);
+	hr_ext_state_t s = ext->state;
+	fibril_rwlock_read_unlock(&vol->states_lock);
+
+	if (s != HR_EXT_ONLINE && s != HR_EXT_REBUILD) {
+		return EINVAL;
+	}
 
 	fibril_mutex_lock(&vol->md_lock);
 
-	for (size_t i = 0; i < vol->extent_no; i++) {
-		hr_extent_t *ext = &vol->extents[i];
-
-		fibril_rwlock_read_lock(&vol->states_lock);
-		hr_ext_state_t s = ext->state;
-
-		if (s != HR_EXT_ONLINE && s != HR_EXT_REBUILD) {
-			fibril_rwlock_read_unlock(&vol->states_lock);
-			continue;
-		}
-
-		fibril_rwlock_read_unlock(&vol->states_lock);
-
-		md->index = i;
-		if (s == HR_EXT_REBUILD)
-			md->rebuild_pos = vol->rebuild_blk;
-		else
-			md->rebuild_pos = 0;
-		meta_native_encode(md, md_block);
-		rc = meta_native_write_block(ext->svc_id, md_block);
-		if (rc != EOK && with_state_callback)
-			vol->hr_ops.ext_state_cb(vol, i, rc);
-	}
+	md->index = ext_idx;
+	if (s == HR_EXT_REBUILD)
+		md->rebuild_pos = vol->rebuild_blk;
+	else
+		md->rebuild_pos = 0;
+	meta_native_encode(md, md_block);
+	errno_t rc = meta_native_write_block(ext->svc_id, md_block);
+	if (rc != EOK && with_state_callback)
+		vol->hr_ops.ext_state_cb(vol, ext_idx, rc);
 
 	fibril_mutex_unlock(&vol->md_lock);
-
-	fibril_rwlock_read_unlock(&vol->extents_lock);
 
 	if (with_state_callback)
Index: uspace/srv/bd/hr/raid1.c
===================================================================
--- uspace/srv/bd/hr/raid1.c	(revision e0695cef2a4a4392f323e3f0212caa45f2b409ee)
+++ uspace/srv/bd/hr/raid1.c	(revision 6a8c1569d31b7ba25b64484de060d2f88525c8d9)
@@ -520,5 +520,6 @@
 
 		if (written * vol->bsize > HR_REBUILD_SAVE_BYTES) {
-			vol->meta_ops->save(vol, WITH_STATE_CALLBACK);
+			vol->meta_ops->save_ext(vol, rebuild_idx,
+			    WITH_STATE_CALLBACK);
 			written = 0;
 		}
Index: uspace/srv/bd/hr/raid5.c
===================================================================
--- uspace/srv/bd/hr/raid5.c	(revision e0695cef2a4a4392f323e3f0212caa45f2b409ee)
+++ uspace/srv/bd/hr/raid5.c	(revision 6a8c1569d31b7ba25b64484de060d2f88525c8d9)
@@ -819,5 +819,6 @@
 
 		if (written * vol->bsize > HR_REBUILD_SAVE_BYTES) {
-			vol->meta_ops->save(vol, WITH_STATE_CALLBACK);
+			vol->meta_ops->save_ext(vol, rebuild_idx,
+			    WITH_STATE_CALLBACK);
 			written = 0;
 		}
Index: uspace/srv/bd/hr/superblock.h
===================================================================
--- uspace/srv/bd/hr/superblock.h	(revision e0695cef2a4a4392f323e3f0212caa45f2b409ee)
+++ uspace/srv/bd/hr/superblock.h	(revision 6a8c1569d31b7ba25b64484de060d2f88525c8d9)
@@ -56,4 +56,5 @@
 	void (*inc_counter)(hr_volume_t *);
 	errno_t (*save)(hr_volume_t *, bool);
+	errno_t (*save_ext)(hr_volume_t *, size_t, bool);
 	const char *(*get_devname)(const void *);
 	hr_level_t (*get_level)(const void *);
