Li Zefan
2010-Nov-19 01:36 UTC
[PATCH 1/2] btrfs: Check if dest_offset is block-size aligned before cloning file
We''ve done the check for src_offset and src_length, and We should also check dest_offset, otherwise we''ll corrupt the destination file: (After cloning file1 to file2 with unaligned dest_offset) # cat /mnt/file2 cat: /mnt/file2: Input/output error Signed-off-by: Li Zefan <lizf@cn.fujitsu.com> --- fs/btrfs/ioctl.c | 7 +++---- 1 files changed, 3 insertions(+), 4 deletions(-) diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 463d91b..81b47bd 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -1669,12 +1669,11 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, olen = len = src->i_size - off; /* if we extend to eof, continue to block boundary */ if (off + len == src->i_size) - len = ((src->i_size + bs-1) & ~(bs-1)) - - off; + len = ALIGN(src->i_size, bs) - off; /* verify the end result is block aligned */ - if ((off & (bs-1)) || - ((off + len) & (bs-1))) + if (!IS_ALIGNED(off, bs) || !IS_ALIGNED(off + len, bs) || + !IS_ALIGNED(destoff, bs)) goto out_unlock; /* do any pending delalloc/csum calc on src, one way or -- 1.6.3 -- 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
Set src_offset = 0, src_length = 20K, dest_offset = 20K. And the original filesize of the dest file ''file2'' is 30K: # ls -l /mnt/file2 -rw-r--r-- 1 root root 30720 Nov 18 16:42 /mnt/file2 Now clone file1 to file2, the dest file should be 40K, but it still shows 30K: # ls -l /mnt/file2 -rw-r--r-- 1 root root 30720 Nov 18 16:42 /mnt/file2 Signed-off-by: Li Zefan <lizf@cn.fujitsu.com> --- fs/btrfs/ioctl.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 81b47bd..6b4bfa7 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -1873,8 +1873,8 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, * but shouldn''t round up the file size */ endoff = new_key.offset + datal; - if (endoff > off+olen) - endoff = off+olen; + if (endoff > destoff+olen) + endoff = destoff+olen; if (endoff > inode->i_size) btrfs_i_size_write(inode, endoff); -- 1.6.3 -- 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
Sage Weil
2010-Nov-22 19:09 UTC
Re: [PATCH 1/2] btrfs: Check if dest_offset is block-size aligned before cloning file
On Fri, 19 Nov 2010, Li Zefan wrote:> We''ve done the check for src_offset and src_length, and We should > also check dest_offset, otherwise we''ll corrupt the destination > file: > > (After cloning file1 to file2 with unaligned dest_offset) > # cat /mnt/file2 > cat: /mnt/file2: Input/output error > > Signed-off-by: Li Zefan <lizf@cn.fujitsu.com> > --- > fs/btrfs/ioctl.c | 7 +++---- > 1 files changed, 3 insertions(+), 4 deletions(-) > > diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c > index 463d91b..81b47bd 100644 > --- a/fs/btrfs/ioctl.c > +++ b/fs/btrfs/ioctl.c > @@ -1669,12 +1669,11 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, > olen = len = src->i_size - off; > /* if we extend to eof, continue to block boundary */ > if (off + len == src->i_size) > - len = ((src->i_size + bs-1) & ~(bs-1)) > - - off; > + len = ALIGN(src->i_size, bs) - off; > > /* verify the end result is block aligned */ > - if ((off & (bs-1)) || > - ((off + len) & (bs-1))) > + if (!IS_ALIGNED(off, bs) || !IS_ALIGNED(off + len, bs) || > + !IS_ALIGNED(destoff, bs)) > goto out_unlock; > > /* do any pending delalloc/csum calc on src, one way orLooks good. Reviewed-by: Sage Weil <sage@newdream.net> -- 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
Sage Weil
2010-Nov-22 19:10 UTC
Re: [PATCH 2/2] btrfs: Set file size correctly in file clone
On Fri, 19 Nov 2010, Li Zefan wrote:> Set src_offset = 0, src_length = 20K, dest_offset = 20K. And the > original filesize of the dest file ''file2'' is 30K: > > # ls -l /mnt/file2 > -rw-r--r-- 1 root root 30720 Nov 18 16:42 /mnt/file2 > > Now clone file1 to file2, the dest file should be 40K, but it > still shows 30K: > > # ls -l /mnt/file2 > -rw-r--r-- 1 root root 30720 Nov 18 16:42 /mnt/file2 > > Signed-off-by: Li Zefan <lizf@cn.fujitsu.com> > --- > fs/btrfs/ioctl.c | 4 ++-- > 1 files changed, 2 insertions(+), 2 deletions(-) > > diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c > index 81b47bd..6b4bfa7 100644 > --- a/fs/btrfs/ioctl.c > +++ b/fs/btrfs/ioctl.c > @@ -1873,8 +1873,8 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, > * but shouldn''t round up the file size > */ > endoff = new_key.offset + datal; > - if (endoff > off+olen) > - endoff = off+olen; > + if (endoff > destoff+olen) > + endoff = destoff+olen; > if (endoff > inode->i_size) > btrfs_i_size_write(inode, endoff);Reviewed-by: Sage Weil <sage@newdream.net> -- 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