mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-10-31 08:44:41 +00:00 
			
		
		
		
	Btrfs: use received_uuid of parent during send
Neil Horman pointed out a problem where if he did something like this receive A snap A B change B send -p A B and then on another box do recieve A receive B the receive B would fail because we use the UUID of A for the clone sources for B. This makes sense most of the time because normally you are sending from the original sources, not a received source. However when you use a recieved subvol its UUID is going to be something completely different, so if you then try to receive the diff on a different volume it won't find the UUID because the new A will be something else. The only constant is the received uuid. So instead check to see if we have received_uuid set on the root, and if so use that as the clone source, as btrfs receive looks for matches either in received_uuid or uuid. Thanks, Reported-by: Neil Horman <nhorman@redhat.com> Signed-off-by: Josef Bacik <jbacik@fb.com> Reviewed-by: Hugo Mills <hugo@carfax.org.uk> Signed-off-by: Chris Mason <clm@fb.com>
This commit is contained in:
		
							parent
							
								
									0eeff2362b
								
							
						
					
					
						commit
						37b8d27de5
					
				
					 1 changed files with 21 additions and 4 deletions
				
			
		|  | @ -2356,8 +2356,12 @@ static int send_subvol_begin(struct send_ctx *sctx) | |||
| 	TLV_PUT_U64(sctx, BTRFS_SEND_A_CTRANSID, | ||||
| 		    le64_to_cpu(sctx->send_root->root_item.ctransid)); | ||||
| 	if (parent_root) { | ||||
| 		TLV_PUT_UUID(sctx, BTRFS_SEND_A_CLONE_UUID, | ||||
| 				sctx->parent_root->root_item.uuid); | ||||
| 		if (!btrfs_is_empty_uuid(parent_root->root_item.received_uuid)) | ||||
| 			TLV_PUT_UUID(sctx, BTRFS_SEND_A_CLONE_UUID, | ||||
| 				     parent_root->root_item.received_uuid); | ||||
| 		else | ||||
| 			TLV_PUT_UUID(sctx, BTRFS_SEND_A_CLONE_UUID, | ||||
| 				     parent_root->root_item.uuid); | ||||
| 		TLV_PUT_U64(sctx, BTRFS_SEND_A_CLONE_CTRANSID, | ||||
| 			    le64_to_cpu(sctx->parent_root->root_item.ctransid)); | ||||
| 	} | ||||
|  | @ -4586,8 +4590,21 @@ verbose_printk("btrfs: send_clone offset=%llu, len=%d, clone_root=%llu, " | |||
| 	if (ret < 0) | ||||
| 		goto out; | ||||
| 
 | ||||
| 	TLV_PUT_UUID(sctx, BTRFS_SEND_A_CLONE_UUID, | ||||
| 			clone_root->root->root_item.uuid); | ||||
| 	/*
 | ||||
| 	 * If the parent we're using has a received_uuid set then use that as | ||||
| 	 * our clone source as that is what we will look for when doing a | ||||
| 	 * receive. | ||||
| 	 * | ||||
| 	 * This covers the case that we create a snapshot off of a received | ||||
| 	 * subvolume and then use that as the parent and try to receive on a | ||||
| 	 * different host. | ||||
| 	 */ | ||||
| 	if (!btrfs_is_empty_uuid(clone_root->root->root_item.received_uuid)) | ||||
| 		TLV_PUT_UUID(sctx, BTRFS_SEND_A_CLONE_UUID, | ||||
| 			     clone_root->root->root_item.received_uuid); | ||||
| 	else | ||||
| 		TLV_PUT_UUID(sctx, BTRFS_SEND_A_CLONE_UUID, | ||||
| 			     clone_root->root->root_item.uuid); | ||||
| 	TLV_PUT_U64(sctx, BTRFS_SEND_A_CLONE_CTRANSID, | ||||
| 		    le64_to_cpu(clone_root->root->root_item.ctransid)); | ||||
| 	TLV_PUT_PATH(sctx, BTRFS_SEND_A_CLONE_PATH, p); | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Josef Bacik
						Josef Bacik