diff options
| author | Ingo Molnar <mingo@elte.hu> | 2010-07-21 15:43:03 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2010-07-21 15:43:06 -0400 |
| commit | 9dcdbf7a33d9018ac5d45debcf261be648bdd56a (patch) | |
| tree | bbcc1a018f11ff76cd7ce174ef3ffe2c02da07ee /fs/btrfs/ioctl.c | |
| parent | cc5edb0eb9ce892b530e34a5d110382483587942 (diff) | |
| parent | cd5b8f8755a89a57fc8c408d284b8b613f090345 (diff) | |
Merge branch 'linus' into perf/core
Merge reason: Pick up the latest perf fixes.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'fs/btrfs/ioctl.c')
| -rw-r--r-- | fs/btrfs/ioctl.c | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 4dbaf89b1337..9254b3d58dbe 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
| @@ -1458,7 +1458,7 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
| 1458 | */ | 1458 | */ |
| 1459 | 1459 | ||
| 1460 | /* the destination must be opened for writing */ | 1460 | /* the destination must be opened for writing */ |
| 1461 | if (!(file->f_mode & FMODE_WRITE)) | 1461 | if (!(file->f_mode & FMODE_WRITE) || (file->f_flags & O_APPEND)) |
| 1462 | return -EINVAL; | 1462 | return -EINVAL; |
| 1463 | 1463 | ||
| 1464 | ret = mnt_want_write(file->f_path.mnt); | 1464 | ret = mnt_want_write(file->f_path.mnt); |
| @@ -1511,7 +1511,7 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
| 1511 | 1511 | ||
| 1512 | /* determine range to clone */ | 1512 | /* determine range to clone */ |
| 1513 | ret = -EINVAL; | 1513 | ret = -EINVAL; |
| 1514 | if (off >= src->i_size || off + len > src->i_size) | 1514 | if (off + len > src->i_size || off + len < off) |
| 1515 | goto out_unlock; | 1515 | goto out_unlock; |
| 1516 | if (len == 0) | 1516 | if (len == 0) |
| 1517 | olen = len = src->i_size - off; | 1517 | olen = len = src->i_size - off; |
| @@ -1578,6 +1578,7 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
| 1578 | u64 disko = 0, diskl = 0; | 1578 | u64 disko = 0, diskl = 0; |
| 1579 | u64 datao = 0, datal = 0; | 1579 | u64 datao = 0, datal = 0; |
| 1580 | u8 comp; | 1580 | u8 comp; |
| 1581 | u64 endoff; | ||
| 1581 | 1582 | ||
| 1582 | size = btrfs_item_size_nr(leaf, slot); | 1583 | size = btrfs_item_size_nr(leaf, slot); |
| 1583 | read_extent_buffer(leaf, buf, | 1584 | read_extent_buffer(leaf, buf, |
| @@ -1712,9 +1713,18 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
| 1712 | btrfs_release_path(root, path); | 1713 | btrfs_release_path(root, path); |
| 1713 | 1714 | ||
| 1714 | inode->i_mtime = inode->i_ctime = CURRENT_TIME; | 1715 | inode->i_mtime = inode->i_ctime = CURRENT_TIME; |
| 1715 | if (new_key.offset + datal > inode->i_size) | 1716 | |
| 1716 | btrfs_i_size_write(inode, | 1717 | /* |
| 1717 | new_key.offset + datal); | 1718 | * we round up to the block size at eof when |
| 1719 | * determining which extents to clone above, | ||
| 1720 | * but shouldn't round up the file size | ||
| 1721 | */ | ||
| 1722 | endoff = new_key.offset + datal; | ||
| 1723 | if (endoff > off+olen) | ||
| 1724 | endoff = off+olen; | ||
| 1725 | if (endoff > inode->i_size) | ||
| 1726 | btrfs_i_size_write(inode, endoff); | ||
| 1727 | |||
| 1718 | BTRFS_I(inode)->flags = BTRFS_I(src)->flags; | 1728 | BTRFS_I(inode)->flags = BTRFS_I(src)->flags; |
| 1719 | ret = btrfs_update_inode(trans, root, inode); | 1729 | ret = btrfs_update_inode(trans, root, inode); |
| 1720 | BUG_ON(ret); | 1730 | BUG_ON(ret); |
