| From f8f484d1b6677dd5cd5e7e605db747e8c30bbd47 Mon Sep 17 00:00:00 2001 |
| From: Tyler Hicks <tyhicks@linux.vnet.ibm.com> |
| Date: Wed, 4 Nov 2009 02:48:01 -0600 |
| Subject: eCryptfs: Add getattr function |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| From: Tyler Hicks <tyhicks@linux.vnet.ibm.com> |
| |
| commit f8f484d1b6677dd5cd5e7e605db747e8c30bbd47 upstream. |
| |
| The i_blocks field of an eCryptfs inode cannot be trusted, but |
| generic_fillattr() uses it to instantiate the blocks field of a stat() |
| syscall when a filesystem doesn't implement its own getattr(). Users |
| have noticed that the output of du is incorrect on newly created files. |
| |
| This patch creates ecryptfs_getattr() which calls into the lower |
| filesystem's getattr() so that eCryptfs can use its kstat.blocks value |
| after calling generic_fillattr(). It is important to note that the |
| block count includes the eCryptfs metadata stored in the beginning of |
| the lower file plus any padding used to fill an extent before |
| encryption. |
| |
| https://bugs.launchpad.net/ecryptfs/+bug/390833 |
| |
| Reported-by: Dominic Sacré <dominic.sacre@gmx.de> |
| Signed-off-by: Tyler Hicks <tyhicks@linux.vnet.ibm.com> |
| Cc: Tim Gardner <timg@tpi.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| fs/ecryptfs/inode.c | 16 ++++++++++++++++ |
| 1 file changed, 16 insertions(+) |
| |
| --- a/fs/ecryptfs/inode.c |
| +++ b/fs/ecryptfs/inode.c |
| @@ -971,6 +971,21 @@ out: |
| return rc; |
| } |
| |
| +int ecryptfs_getattr(struct vfsmount *mnt, struct dentry *dentry, |
| + struct kstat *stat) |
| +{ |
| + struct kstat lower_stat; |
| + int rc; |
| + |
| + rc = vfs_getattr(ecryptfs_dentry_to_lower_mnt(dentry), |
| + ecryptfs_dentry_to_lower(dentry), &lower_stat); |
| + if (!rc) { |
| + generic_fillattr(dentry->d_inode, stat); |
| + stat->blocks = lower_stat.blocks; |
| + } |
| + return rc; |
| +} |
| + |
| int |
| ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value, |
| size_t size, int flags) |
| @@ -1100,6 +1115,7 @@ const struct inode_operations ecryptfs_d |
| const struct inode_operations ecryptfs_main_iops = { |
| .permission = ecryptfs_permission, |
| .setattr = ecryptfs_setattr, |
| + .getattr = ecryptfs_getattr, |
| .setxattr = ecryptfs_setxattr, |
| .getxattr = ecryptfs_getxattr, |
| .listxattr = ecryptfs_listxattr, |