diff mbox

btrfs-progs: subvol sync: fix memory corruption, undersized array

Message ID 1458211640-13106-1-git-send-email-dsterba@suse.com (mailing list archive)
State Accepted
Headers show

Commit Message

David Sterba March 17, 2016, 10:47 a.m. UTC
The subvol sync command crashed randomly at the end with

*** glibc detected *** btrfs: double free or corruption (out): 0x00000000006ab040 ***

This is caused by running out of the ids array in case there are more
than 128 subvolumes. The array is increased in steps but does not
account the size of the item, so there was room for 1024 / 8 = 128
subvolume ids.

Fixes: c9f885ec8963 ("btrfs-progs: subvol: let sync check only current deletions")
Signed-off-by: David Sterba <dsterba@suse.com>
---
 cmds-subvolume.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

Comments

sri March 17, 2016, 2:10 p.m. UTC | #1
Hi,

I Would like to know between 2 snapshots of a subvolume, can we identify 
what all blocks modified particular to that subvolume ?

there can be many subvolume and snapshots present on the btrfs but i want 
only blocks modified since first snapshot for the specific subvolume.

blocks should include metadata and data blocks. 


--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Henk Slager March 17, 2016, 8:36 p.m. UTC | #2
sri <toyours_sridhar <at> yahoo.co.in> writes:

> 
> Hi,
> 
> I Would like to know between 2 snapshots of a subvolume, can we identify 
> what all blocks modified particular to that subvolume ?
> 
> there can be many subvolume and snapshots present on the btrfs but i want 
> only blocks modified since first snapshot for the specific subvolume.
> 
> blocks should include metadata and data blocks. 

Not directly diff blocks, rather files, you could do something like this:

btrfs subvolume find-new <newer_snapshot> `btrfs subvolume show 
<older_snapshot> | grep Generation | awk '{print $2}'` |  awk '{ print $17 }' 
| sort | uniq


--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
sri March 18, 2016, 1:36 p.m. UTC | #3
Henk Slager <eye1tm <at> gmail.com> writes:

> 
> sri <toyours_sridhar <at> yahoo.co.in> writes:
> 
> > 
> > Hi,
> > 
> > I Would like to know between 2 snapshots of a subvolume, can we 
identify 
> > what all blocks modified particular to that subvolume ?
> > 
> > there can be many subvolume and snapshots present on the btrfs but i 
want 
> > only blocks modified since first snapshot for the specific 
subvolume.
> > 
> > blocks should include metadata and data blocks. 
> 
> Not directly diff blocks, rather files, you could do something like 
this:
> 
> btrfs subvolume find-new <newer_snapshot> `btrfs subvolume show 
> <older_snapshot> | grep Generation | awk '{print $2}'` |  awk '{ print 
$17 }' 
> | sort | uniq
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-btrfs" 
in
> the body of a message to majordomo <at> vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> 

Thank you. As I checked only blocks related to file are shown. 

sample output:

btrfs subvolume find-new snap2 15
inode 264 file offset 0 len 8192 disk start 351559680 offset 0 gen 16 
flags NONE mman.h
inode 265 file offset 0 len 8192 disk start 351567872 offset 0 gen 16 
flags NONE mount.h
inode 266 file offset 0 len 2374 disk start 0 offset 0 gen 16 flags 
INLINE msg.h
inode 267 file offset 0 len 12288 disk start 351576064 offset 0 gen 16 
flags NONE mtio.h
transid marker was 16


I think it showed blocks changed w.r.t file data block.

is there a way to get other blocks modified such as meta data such as 
inodes blocks modified and corresponding directory inode blocks along 
with files?

Above fs is created on 2 disks /dev/sdd and /dev/sdd of 3 gb.  No raid 
configured. I think it is just strped with 6gb size around.

How should I interpret:
inode 266 file offset 0 len 2374 disk start 0 offset 0 gen 16 flags 
INLINE msg.h

??

disk start is 0 here. Is this w.r.t what?

and offset 0 is offset inside block represented by disk start ?


thank you.







--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Duncan March 19, 2016, 12:13 a.m. UTC | #4
sri posted on Fri, 18 Mar 2016 13:36:50 +0000 as excerpted:

> Henk Slager <eye1tm <at> gmail.com> writes:
> 
>> sri <toyours_sridhar <at> yahoo.co.in> writes:
>> > 
>> > I Would like to know between 2 snapshots of a subvolume, can we
>> > identify what all blocks modified particular to that subvolume ?
>> > 
>> > there can be many subvolume and snapshots present on the btrfs but i
>> > want only blocks modified since first snapshot for the specific
>> > subvolume.  blocks should include metadata and data blocks.
>> 
>> Not directly diff blocks, rather files, you could do something like
>> this:
>> 
>> btrfs subvolume find-new [...]
>> 
>> 
> Thank you. As I checked only blocks related to file are shown.
> 
> is there a way to get other blocks modified such as meta data such as
> inodes blocks modified and corresponding directory inode blocks along
> with files?

This would include the change data itself as well, and I'm not sure if 
the format once the actual binary level changes themselves are removed is 
practically consumable by humans or not, but it occurs to me that this is 
precisely the information that btrfs send -p provides.  If you can strip 
the changes themselves out and what's left is either human readable or 
can be processed to human readable, then it should be exactly what you're 
after, the changed blocks, for data and metadata both.
diff mbox

Patch

diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index 02e1dec18ed2..32caaa5db9ec 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -1204,7 +1204,8 @@  static int enumerate_dead_subvols(int fd, u64 **ids)
 					u64 *newids;
 
 					count += SUBVOL_ID_BATCH;
-					newids = (u64*)realloc(*ids, count);
+					newids = (u64*)realloc(*ids,
+							count * sizeof(u64));
 					if (!newids)
 						return -ENOMEM;
 					*ids = newids;