snapshots on unaligned lvs
PATCH 1/1 snapshots on unaligned lvs
Hello everyone,
This patch fixes 1.0.1-rc4 to be able to take snapshots of unaligned logical volumes (created by some of the betas). It also fixes a counting error in the loop in lvm_snapshot_COW.
Nothing fancy here, I just changed it to use the hard sector size as the blocksize sent to brw_kiovec. I've tested with beta7 and rc4 logical volumes, additional testing is more than welcome.
-chris
drivers/md/lvm-snap.c Thu, 11 Oct 2001 14:11:50 -0400 renamed from drivers/md/lvm-snap.c Thu, 11 Oct 2001 10:17:22 -0400 +15 -5
@@ -326,6 +326,7 @@ { const char * reason; unsigned long org_start, snap_start, snap_phys_dev, virt_start, pe_off; + unsigned long phys_start ; int idx = lv_snap->lv_remap_ptr, chunk_size = lv_snap->lv_chunk_size; struct kiobuf * iobuf; unsigned long blocks[KIO_MAX_SECTORS];
@@ -360,8 +361,14 @@ iobuf = lv_snap->lv_iobuf; - blksize_org = lvm_get_blksize(org_phys_dev); - blksize_snap = lvm_get_blksize(snap_phys_dev); + blksize_org = get_hardsect_size(org_phys_dev); + blksize_snap = get_hardsect_size(snap_phys_dev); + + /* org_start must not change, we use it later on to fill in the + ** exception table + */ + phys_start = org_start ; + max_blksize = max(blksize_org, blksize_snap); min_blksize = min(blksize_org, blksize_snap); max_sectors = KIO_MAX_SECTORS * (min_blksize>>9);
@@ -376,7 +383,7 @@ iobuf->length = nr_sectors << 9; - if(!lvm_snapshot_prepare_blocks(blocks, org_start, + if(!lvm_snapshot_prepare_blocks(blocks, phys_start, nr_sectors, blksize_org)) goto fail_prepare;
@@ -391,6 +398,9 @@ if (__brw_kiovec(WRITE, 1, &iobuf, snap_phys_dev, blocks, blksize_snap, lv_snap) != (nr_sectors<<9)) goto fail_raw_write; + + phys_start += nr_sectors ; + snap_start += nr_sectors ; } #ifdef DEBUG_SNAPSHOT
@@ -605,7 +615,7 @@ snap_phys_dev = lv_snap->lv_block_exception[idx].rdev_new; snap_pe_start = lv_snap->lv_block_exception[idx - (idx % COW_entries_per_pe)].rsector_new - lv_snap->lv_chunk_size; - blksize_snap = lvm_get_blksize(snap_phys_dev); + blksize_snap = get_hardsect_size(snap_phys_dev); COW_entries_per_block = blksize_snap / sizeof(lv_COW_table_disk_t); idx_COW_table = idx % COW_entries_per_pe % COW_entries_per_block;
@@ -654,7 +664,7 @@ idx++; snap_phys_dev = lv_snap->lv_block_exception[idx].rdev_new; snap_pe_start = lv_snap->lv_block_exception[idx - (idx % COW_entries_per_pe)].rsector_new - lv_snap->lv_chunk_size; - blksize_snap = lvm_get_blksize(snap_phys_dev); + blksize_snap = get_hardsect_size(snap_phys_dev); blocks[0] = snap_pe_start >> (blksize_snap >> 10); } else blocks[0]++;
drivers/md/lvm-snap.c Thu, 11 Oct 2001 14:11:50 -0400 line 365
Quoted 8 lines · Chris Mason
drivers/md/lvm-snap.c Thu, 11 Oct 2001 14:11:50 -0400 renamed from drivers/md/lvm-snap.c Thu, 11 Oct 2001 10:17:22 -0400 +2
-2@@ -360,8 +361,14 @@ iobuf = lv_snap->lv_iobuf; - blksize_org = lvm_get_blksize(org_phys_dev); - blksize_snap = lvm_get_blksize(snap_phys_dev); + blksize_org = get_hardsect_size(org_phys_dev); + blksize_snap = get_hardsect_size(snap_phys_dev);
FYI - there is now a helper function "lvm_sectsize()" which is defined appropriately for a given kernel version to call get_hardsect_size() or get_hardblock_size(). I originally put it directly in lvm.c because that was the only place we used it, but it should move to lvm-internal.h instead.
I won't check in this patch until I at least hear some Yea's as I can't do any testing on it myself right now. Of course the Sistina folks are free to test/commit it as well.
Cheers, Andreas
--
Andreas Dilger \ "If a man ate a pound of pasta and a pound of antipasto,
\ would they cancel out, leaving him still hungry?"
http://www-mddsp.enel.ucalgary.ca/People/adilger/ -- Dogbert