Revert Btrfs ro snapshot commit that causes filesystem corruption
This commit is contained in:
		
							parent
							
								
									e1712de563
								
							
						
					
					
						commit
						ec4608962e
					
				
							
								
								
									
										105
									
								
								Revert-Btrfs-race-free-update-of-commit-root-for-ro-.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								Revert-Btrfs-race-free-update-of-commit-root-for-ro-.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,105 @@ | |||||||
|  | From: Josh Boyer <jwboyer@fedoraproject.org> | ||||||
|  | Date: Wed, 15 Oct 2014 10:09:50 -0400 | ||||||
|  | Subject: [PATCH] Revert "Btrfs: race free update of commit root for ro | ||||||
|  |  snapshots" | ||||||
|  | 
 | ||||||
|  | This reverts commit 9c3b306e1c9e6be4be09e99a8fe2227d1005effc. | ||||||
|  | ---
 | ||||||
|  |  fs/btrfs/inode.c | 36 ------------------------------------ | ||||||
|  |  fs/btrfs/ioctl.c | 33 +++++++++++++++++++++++++++++++++ | ||||||
|  |  2 files changed, 33 insertions(+), 36 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
 | ||||||
|  | index fc9c0439caa3..d23362f4464e 100644
 | ||||||
|  | --- a/fs/btrfs/inode.c
 | ||||||
|  | +++ b/fs/btrfs/inode.c
 | ||||||
|  | @@ -5261,42 +5261,6 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry)
 | ||||||
|  |  			iput(inode); | ||||||
|  |  			inode = ERR_PTR(ret); | ||||||
|  |  		} | ||||||
|  | -		/*
 | ||||||
|  | -		 * If orphan cleanup did remove any orphans, it means the tree
 | ||||||
|  | -		 * was modified and therefore the commit root is not the same as
 | ||||||
|  | -		 * the current root anymore. This is a problem, because send
 | ||||||
|  | -		 * uses the commit root and therefore can see inode items that
 | ||||||
|  | -		 * don't exist in the current root anymore, and for example make
 | ||||||
|  | -		 * calls to btrfs_iget, which will do tree lookups based on the
 | ||||||
|  | -		 * current root and not on the commit root. Those lookups will
 | ||||||
|  | -		 * fail, returning a -ESTALE error, and making send fail with
 | ||||||
|  | -		 * that error. So make sure a send does not see any orphans we
 | ||||||
|  | -		 * have just removed, and that it will see the same inodes
 | ||||||
|  | -		 * regardless of whether a transaction commit happened before
 | ||||||
|  | -		 * it started (meaning that the commit root will be the same as
 | ||||||
|  | -		 * the current root) or not.
 | ||||||
|  | -		 */
 | ||||||
|  | -		if (sub_root->node != sub_root->commit_root) {
 | ||||||
|  | -			u64 sub_flags = btrfs_root_flags(&sub_root->root_item);
 | ||||||
|  | -
 | ||||||
|  | -			if (sub_flags & BTRFS_ROOT_SUBVOL_RDONLY) {
 | ||||||
|  | -				struct extent_buffer *eb;
 | ||||||
|  | -
 | ||||||
|  | -				/*
 | ||||||
|  | -				 * Assert we can't have races between dentry
 | ||||||
|  | -				 * lookup called through the snapshot creation
 | ||||||
|  | -				 * ioctl and the VFS.
 | ||||||
|  | -				 */
 | ||||||
|  | -				ASSERT(mutex_is_locked(&dir->i_mutex));
 | ||||||
|  | -
 | ||||||
|  | -				down_write(&root->fs_info->commit_root_sem);
 | ||||||
|  | -				eb = sub_root->commit_root;
 | ||||||
|  | -				sub_root->commit_root =
 | ||||||
|  | -					btrfs_root_node(sub_root);
 | ||||||
|  | -				up_write(&root->fs_info->commit_root_sem);
 | ||||||
|  | -				free_extent_buffer(eb);
 | ||||||
|  | -			}
 | ||||||
|  | -		}
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	return inode; | ||||||
|  | diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
 | ||||||
|  | index 0fe1aa047f15..8d2b76e29d3b 100644
 | ||||||
|  | --- a/fs/btrfs/ioctl.c
 | ||||||
|  | +++ b/fs/btrfs/ioctl.c
 | ||||||
|  | @@ -713,6 +713,39 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir,
 | ||||||
|  |  	if (ret) | ||||||
|  |  		goto fail; | ||||||
|  |   | ||||||
|  | +	ret = btrfs_orphan_cleanup(pending_snapshot->snap);
 | ||||||
|  | +	if (ret)
 | ||||||
|  | +		goto fail;
 | ||||||
|  | +
 | ||||||
|  | +	/*
 | ||||||
|  | +	 * If orphan cleanup did remove any orphans, it means the tree was
 | ||||||
|  | +	 * modified and therefore the commit root is not the same as the
 | ||||||
|  | +	 * current root anymore. This is a problem, because send uses the
 | ||||||
|  | +	 * commit root and therefore can see inode items that don't exist
 | ||||||
|  | +	 * in the current root anymore, and for example make calls to
 | ||||||
|  | +	 * btrfs_iget, which will do tree lookups based on the current root
 | ||||||
|  | +	 * and not on the commit root. Those lookups will fail, returning a
 | ||||||
|  | +	 * -ESTALE error, and making send fail with that error. So make sure
 | ||||||
|  | +	 * a send does not see any orphans we have just removed, and that it
 | ||||||
|  | +	 * will see the same inodes regardless of whether a transaction
 | ||||||
|  | +	 * commit happened before it started (meaning that the commit root
 | ||||||
|  | +	 * will be the same as the current root) or not.
 | ||||||
|  | +	 */
 | ||||||
|  | +	if (readonly && pending_snapshot->snap->node !=
 | ||||||
|  | +	    pending_snapshot->snap->commit_root) {
 | ||||||
|  | +		trans = btrfs_join_transaction(pending_snapshot->snap);
 | ||||||
|  | +		if (IS_ERR(trans) && PTR_ERR(trans) != -ENOENT) {
 | ||||||
|  | +			ret = PTR_ERR(trans);
 | ||||||
|  | +			goto fail;
 | ||||||
|  | +		}
 | ||||||
|  | +		if (!IS_ERR(trans)) {
 | ||||||
|  | +			ret = btrfs_commit_transaction(trans,
 | ||||||
|  | +						       pending_snapshot->snap);
 | ||||||
|  | +			if (ret)
 | ||||||
|  | +				goto fail;
 | ||||||
|  | +		}
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  |  	inode = btrfs_lookup_dentry(dentry->d_parent->d_inode, dentry); | ||||||
|  |  	if (IS_ERR(inode)) { | ||||||
|  |  		ret = PTR_ERR(inode); | ||||||
|  | -- 
 | ||||||
|  | 1.9.3 | ||||||
|  | 
 | ||||||
| @ -609,6 +609,8 @@ Patch26037: HID-usbhid-always-poll-quirk-for-Elan-Touchscreen-00.patch | |||||||
| Patch26038: USB-quirks-device-qualifier-quirk-for-another-Elan-t.patch | Patch26038: USB-quirks-device-qualifier-quirk-for-another-Elan-t.patch | ||||||
| Patch26039: HID-usbhid-always-poll-quirk-for-Elan-Touchscreen-01.patch | Patch26039: HID-usbhid-always-poll-quirk-for-Elan-Touchscreen-01.patch | ||||||
| 
 | 
 | ||||||
|  | Patch26040: Revert-Btrfs-race-free-update-of-commit-root-for-ro-.patch | ||||||
|  | 
 | ||||||
| # git clone ssh://git.fedorahosted.org/git/kernel-arm64.git, git diff master...devel | # git clone ssh://git.fedorahosted.org/git/kernel-arm64.git, git diff master...devel | ||||||
| Patch30000: kernel-arm64.patch | Patch30000: kernel-arm64.patch | ||||||
| 
 | 
 | ||||||
| @ -1330,6 +1332,8 @@ ApplyPatch HID-usbhid-always-poll-quirk-for-Elan-Touchscreen-00.patch | |||||||
| ApplyPatch USB-quirks-device-qualifier-quirk-for-another-Elan-t.patch | ApplyPatch USB-quirks-device-qualifier-quirk-for-another-Elan-t.patch | ||||||
| ApplyPatch HID-usbhid-always-poll-quirk-for-Elan-Touchscreen-01.patch | ApplyPatch HID-usbhid-always-poll-quirk-for-Elan-Touchscreen-01.patch | ||||||
| 
 | 
 | ||||||
|  | ApplyPatch Revert-Btrfs-race-free-update-of-commit-root-for-ro-.patch | ||||||
|  | 
 | ||||||
| %if 0%{?aarch64patches} | %if 0%{?aarch64patches} | ||||||
| ApplyPatch kernel-arm64.patch | ApplyPatch kernel-arm64.patch | ||||||
| %ifnarch aarch64 # this is stupid, but i want to notice before secondary koji does. | %ifnarch aarch64 # this is stupid, but i want to notice before secondary koji does. | ||||||
| @ -2198,6 +2202,9 @@ fi | |||||||
| #                                    ||----w | | #                                    ||----w | | ||||||
| #                                    ||     || | #                                    ||     || | ||||||
| %changelog | %changelog | ||||||
|  | * Wed Oct 15 2014 Josh Boyer <jwboyer@fedoraproject.org> | ||||||
|  | - Revert Btrfs ro snapshot commit that causes filesystem corruption | ||||||
|  | 
 | ||||||
| * Wed Oct 15 2014 Josh Boyer <jwboyer@fedoraproject.org> - 3.18.0-0.rc0.git9.1 | * Wed Oct 15 2014 Josh Boyer <jwboyer@fedoraproject.org> - 3.18.0-0.rc0.git9.1 | ||||||
| - Linux v3.17-9670-g0429fbc0bdc2 | - Linux v3.17-9670-g0429fbc0bdc2 | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user