diff options
author | Tyler Hicks <tyhicks@linux.vnet.ibm.com> | 2009-11-04 03:48:01 -0500 |
---|---|---|
committer | Tyler Hicks <tyhicks@linux.vnet.ibm.com> | 2010-01-19 23:32:09 -0500 |
commit | f8f484d1b6677dd5cd5e7e605db747e8c30bbd47 (patch) | |
tree | 67acfc58f5e952e4fd2720d2e5e77409db40b6b8 /fs/ecryptfs/inode.c | |
parent | 5f3ef64f4da1c587cdcfaaac72311225b7df094c (diff) |
eCryptfs: Add getattr function
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>
Diffstat (limited to 'fs/ecryptfs/inode.c')
-rw-r--r-- | fs/ecryptfs/inode.c | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 2b449d79b7fa..5726d7adaf5b 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
@@ -1006,6 +1006,21 @@ out: | |||
1006 | return rc; | 1006 | return rc; |
1007 | } | 1007 | } |
1008 | 1008 | ||
1009 | int ecryptfs_getattr(struct vfsmount *mnt, struct dentry *dentry, | ||
1010 | struct kstat *stat) | ||
1011 | { | ||
1012 | struct kstat lower_stat; | ||
1013 | int rc; | ||
1014 | |||
1015 | rc = vfs_getattr(ecryptfs_dentry_to_lower_mnt(dentry), | ||
1016 | ecryptfs_dentry_to_lower(dentry), &lower_stat); | ||
1017 | if (!rc) { | ||
1018 | generic_fillattr(dentry->d_inode, stat); | ||
1019 | stat->blocks = lower_stat.blocks; | ||
1020 | } | ||
1021 | return rc; | ||
1022 | } | ||
1023 | |||
1009 | int | 1024 | int |
1010 | ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value, | 1025 | ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value, |
1011 | size_t size, int flags) | 1026 | size_t size, int flags) |
@@ -1135,6 +1150,7 @@ const struct inode_operations ecryptfs_dir_iops = { | |||
1135 | const struct inode_operations ecryptfs_main_iops = { | 1150 | const struct inode_operations ecryptfs_main_iops = { |
1136 | .permission = ecryptfs_permission, | 1151 | .permission = ecryptfs_permission, |
1137 | .setattr = ecryptfs_setattr, | 1152 | .setattr = ecryptfs_setattr, |
1153 | .getattr = ecryptfs_getattr, | ||
1138 | .setxattr = ecryptfs_setxattr, | 1154 | .setxattr = ecryptfs_setxattr, |
1139 | .getxattr = ecryptfs_getxattr, | 1155 | .getxattr = ecryptfs_getxattr, |
1140 | .listxattr = ecryptfs_listxattr, | 1156 | .listxattr = ecryptfs_listxattr, |