diff options
author | Chris Mason <chris.mason@oracle.com> | 2011-09-18 10:31:44 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2011-09-18 10:31:44 -0400 |
commit | 2cf4ce7c2a07782c3f4d899b380a78522bca3238 (patch) | |
tree | 46ef48fd4ee47753d6539b65c8a90a2f64e9f8a5 /fs/btrfs/ioctl.c | |
parent | b6fd41e29dea9c6753b1843a77e50433e6123bcb (diff) | |
parent | dde820fbf7176b64daddc1856597d9c61dac19e2 (diff) |
Merge branch 'btrfs-3.0' into for-linus
Diffstat (limited to 'fs/btrfs/ioctl.c')
-rw-r--r-- | fs/btrfs/ioctl.c | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 3351b1b2457..d11fd28efa6 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -2177,6 +2177,11 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, if (!(src_file->f_mode & FMODE_READ)) goto out_fput; + /* don't make the dst file partly checksummed */ + if ((BTRFS_I(src)->flags & BTRFS_INODE_NODATASUM) != + (BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM)) + goto out_fput; + ret = -EISDIR; if (S_ISDIR(src->i_mode) || S_ISDIR(inode->i_mode)) goto out_fput; @@ -2226,6 +2231,10 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, goto out_unlock; } + /* truncate page cache pages from target inode range */ + truncate_inode_pages_range(&inode->i_data, destoff, + PAGE_CACHE_ALIGN(destoff + len) - 1); + /* do any pending delalloc/csum calc on src, one way or another, and lock file content */ while (1) { @@ -2242,10 +2251,6 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, btrfs_wait_ordered_range(src, off, len); } - /* truncate page cache pages from target inode range */ - truncate_inode_pages_range(&inode->i_data, off, - ALIGN(off + len, PAGE_CACHE_SIZE) - 1); - /* clone data */ key.objectid = btrfs_ino(src); key.type = BTRFS_EXTENT_DATA_KEY; @@ -2442,7 +2447,6 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, if (endoff > inode->i_size) btrfs_i_size_write(inode, endoff); - BTRFS_I(inode)->flags = BTRFS_I(src)->flags; ret = btrfs_update_inode(trans, root, inode); BUG_ON(ret); btrfs_end_transaction(trans, root); |