| From 8af8eecc1331dbf5e8c662022272cf667e213da5 Mon Sep 17 00:00:00 2001 |
| From: Jan Kara <jack@suse.cz> |
| Date: Fri, 31 May 2013 19:39:56 -0400 |
| Subject: ext4: fix overflow when counting used blocks on 32-bit architectures |
| |
| From: Jan Kara <jack@suse.cz> |
| |
| commit 8af8eecc1331dbf5e8c662022272cf667e213da5 upstream. |
| |
| The arithmetics adding delalloc blocks to the number of used blocks in |
| ext4_getattr() can easily overflow on 32-bit archs as we first multiply |
| number of blocks by blocksize and then divide back by 512. Make the |
| arithmetics more clever and also use proper type (unsigned long long |
| instead of unsigned long). |
| |
| Signed-off-by: Jan Kara <jack@suse.cz> |
| Signed-off-by: Theodore Ts'o <tytso@mit.edu> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| fs/ext4/inode.c | 4 ++-- |
| 1 file changed, 2 insertions(+), 2 deletions(-) |
| |
| --- a/fs/ext4/inode.c |
| +++ b/fs/ext4/inode.c |
| @@ -4616,7 +4616,7 @@ int ext4_getattr(struct vfsmount *mnt, s |
| struct kstat *stat) |
| { |
| struct inode *inode; |
| - unsigned long delalloc_blocks; |
| + unsigned long long delalloc_blocks; |
| |
| inode = dentry->d_inode; |
| generic_fillattr(inode, stat); |
| @@ -4634,7 +4634,7 @@ int ext4_getattr(struct vfsmount *mnt, s |
| delalloc_blocks = EXT4_C2B(EXT4_SB(inode->i_sb), |
| EXT4_I(inode)->i_reserved_data_blocks); |
| |
| - stat->blocks += (delalloc_blocks << inode->i_sb->s_blocksize_bits)>>9; |
| + stat->blocks += delalloc_blocks << (inode->i_sb->s_blocksize_bits-9); |
| return 0; |
| } |
| |