diff options
-rw-r--r-- | fs/ext4/ext4.h | 2 | ||||
-rw-r--r-- | fs/ext4/file.c | 1 | ||||
-rw-r--r-- | fs/ext4/inode.c | 26 |
3 files changed, 29 insertions, 0 deletions
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 0962f4e26579..303e41cf7b14 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h | |||
@@ -1059,6 +1059,8 @@ int ext4_get_blocks_handle(handle_t *handle, struct inode *inode, | |||
1059 | extern struct inode *ext4_iget(struct super_block *, unsigned long); | 1059 | extern struct inode *ext4_iget(struct super_block *, unsigned long); |
1060 | extern int ext4_write_inode (struct inode *, int); | 1060 | extern int ext4_write_inode (struct inode *, int); |
1061 | extern int ext4_setattr (struct dentry *, struct iattr *); | 1061 | extern int ext4_setattr (struct dentry *, struct iattr *); |
1062 | extern int ext4_getattr(struct vfsmount *mnt, struct dentry *dentry, | ||
1063 | struct kstat *stat); | ||
1062 | extern void ext4_delete_inode (struct inode *); | 1064 | extern void ext4_delete_inode (struct inode *); |
1063 | extern int ext4_sync_inode (handle_t *, struct inode *); | 1065 | extern int ext4_sync_inode (handle_t *, struct inode *); |
1064 | extern void ext4_discard_reservation (struct inode *); | 1066 | extern void ext4_discard_reservation (struct inode *); |
diff --git a/fs/ext4/file.c b/fs/ext4/file.c index b9510ba66a2d..430eb7978db4 100644 --- a/fs/ext4/file.c +++ b/fs/ext4/file.c | |||
@@ -161,6 +161,7 @@ const struct file_operations ext4_file_operations = { | |||
161 | const struct inode_operations ext4_file_inode_operations = { | 161 | const struct inode_operations ext4_file_inode_operations = { |
162 | .truncate = ext4_truncate, | 162 | .truncate = ext4_truncate, |
163 | .setattr = ext4_setattr, | 163 | .setattr = ext4_setattr, |
164 | .getattr = ext4_getattr, | ||
164 | #ifdef CONFIG_EXT4DEV_FS_XATTR | 165 | #ifdef CONFIG_EXT4DEV_FS_XATTR |
165 | .setxattr = generic_setxattr, | 166 | .setxattr = generic_setxattr, |
166 | .getxattr = generic_getxattr, | 167 | .getxattr = generic_getxattr, |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 0fbe678d40bb..8ca2763df091 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -4231,6 +4231,32 @@ err_out: | |||
4231 | return error; | 4231 | return error; |
4232 | } | 4232 | } |
4233 | 4233 | ||
4234 | int ext4_getattr(struct vfsmount *mnt, struct dentry *dentry, | ||
4235 | struct kstat *stat) | ||
4236 | { | ||
4237 | struct inode *inode; | ||
4238 | unsigned long delalloc_blocks; | ||
4239 | |||
4240 | inode = dentry->d_inode; | ||
4241 | generic_fillattr(inode, stat); | ||
4242 | |||
4243 | /* | ||
4244 | * We can't update i_blocks if the block allocation is delayed | ||
4245 | * otherwise in the case of system crash before the real block | ||
4246 | * allocation is done, we will have i_blocks inconsistent with | ||
4247 | * on-disk file blocks. | ||
4248 | * We always keep i_blocks updated together with real | ||
4249 | * allocation. But to not confuse with user, stat | ||
4250 | * will return the blocks that include the delayed allocation | ||
4251 | * blocks for this file. | ||
4252 | */ | ||
4253 | spin_lock(&EXT4_I(inode)->i_block_reservation_lock); | ||
4254 | delalloc_blocks = EXT4_I(inode)->i_reserved_data_blocks; | ||
4255 | spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); | ||
4256 | |||
4257 | stat->blocks += (delalloc_blocks << inode->i_sb->s_blocksize_bits)>>9; | ||
4258 | return 0; | ||
4259 | } | ||
4234 | 4260 | ||
4235 | /* | 4261 | /* |
4236 | * How many blocks doth make a writepage()? | 4262 | * How many blocks doth make a writepage()? |