| From c54971dc5bfec904dda4fa3bb3b54f2847e77f5c Mon Sep 17 00:00:00 2001 |
| From: Sarthak Kukreti <sarthakkukreti@chromium.org> |
| Date: Wed, 4 Oct 2017 17:18:20 -0700 |
| Subject: [PATCH] CHROMIUM: vfs: Add support for superblock-level drop_cache |
| |
| Drops caches and evicts inodes for a superblock. Requires |
| CAP_SYS_ADMIN. Used as a workaround, by cryptohome, for clearing |
| cached unencrypted data for ext4 mounts. |
| (forward port from chromeos-4.4). |
| |
| BUG=chromium:703307 |
| TEST=User data is encrypted immediately after logout |
| |
| Conflicts: |
| fs/ioctl.c |
| include/linux/fs.h |
| |
| Change-Id: Ib27c7e7a2e5a186e7fe2e8c3a2864562f156d8f9 |
| Signed-off-by: Sarthak Kukreti <sarthakkukreti@chromium.org> |
| Reviewed-on: https://chromium-review.googlesource.com/701920 |
| Reviewed-by: Eric Biggers <ebiggers@google.com> |
| (cherry picked from commit 96e56ffa00a57f0990f7d0dbf9161668fa11f620) |
| Signed-off-by: Sarthak Kukreti <sarthakkukreti@chromium.org> |
| Reviewed-on: https://chromium-review.googlesource.com/927489 |
| Reviewed-by: Gwendal Grignou <gwendal@chromium.org> |
| |
| Conflicts: |
| fs/compat_ioctl.c (context) |
| |
| [rebase54(groeck): Context conflicts] |
| Signed-off-by: Guenter Roeck <groeck@chromium.org> |
| [rebase510(groeck): Context conflicts, fs/compat_ioctl.c no longer exists] |
| Signed-off-by: Guenter Roeck <groeck@chromium.org> |
| Change-Id: I635bf2dab430bcf182f4fecd2e775ead0685178d |
| --- |
| fs/ioctl.c | 23 +++++++++++++++++++++++ |
| include/linux/fs.h | 1 + |
| include/uapi/linux/fs.h | 7 +++++++ |
| 3 files changed, 31 insertions(+) |
| |
| diff --git a/fs/ioctl.c b/fs/ioctl.c |
| index 1e2204fa9963..167bcfab0084 100644 |
| --- a/fs/ioctl.c |
| +++ b/fs/ioctl.c |
| @@ -961,6 +961,26 @@ static int ioctl_fssetxattr(struct file *file, void __user *argp) |
| return err; |
| } |
| |
| +/** |
| + * ioctl_drop_cache - drop all caches for a superblock |
| + * |
| + * @sb: superblock to drop caches for |
| + * |
| + * Clears the dcache and evicts all inodes for a mount |
| + * |
| + * Returns 0 on success, -EPERM on permission failure. |
| + */ |
| +static int ioctl_drop_cache(struct super_block *sb) |
| +{ |
| + if (!capable(CAP_SYS_ADMIN)) |
| + return -EPERM; |
| + |
| + shrink_dcache_sb(sb); |
| + invalidate_inodes(sb, false); |
| + |
| + return 0; |
| +} |
| + |
| /* |
| * do_vfs_ioctl() is not for drivers and not intended to be EXPORT_SYMBOL()'d. |
| * It's just a simple helper for sys_ioctl and compat_sys_ioctl. |
| @@ -1043,6 +1063,9 @@ static int do_vfs_ioctl(struct file *filp, unsigned int fd, |
| case FS_IOC_FSSETXATTR: |
| return ioctl_fssetxattr(filp, argp); |
| |
| + case FS_IOC_DROP_CACHE: |
| + return ioctl_drop_cache(inode->i_sb); |
| + |
| default: |
| if (S_ISREG(inode->i_mode)) |
| return file_ioctl(filp, cmd, argp); |
| diff --git a/include/linux/fs.h b/include/linux/fs.h |
| index c3c88fdb9b2a..39594a5ac7e7 100644 |
| --- a/include/linux/fs.h |
| +++ b/include/linux/fs.h |
| @@ -3394,6 +3394,7 @@ extern struct super_block *get_super(struct block_device *); |
| extern struct super_block *get_active_super(struct block_device *bdev); |
| extern void drop_super(struct super_block *sb); |
| extern void drop_super_exclusive(struct super_block *sb); |
| +extern int invalidate_inodes(struct super_block *sb, bool kill_dirty); |
| extern void iterate_supers(void (*)(struct super_block *, void *), void *); |
| extern void iterate_supers_type(struct file_system_type *, |
| void (*)(struct super_block *, void *), void *); |
| diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h |
| index 4c32e97dcdf0..8d83440d4638 100644 |
| --- a/include/uapi/linux/fs.h |
| +++ b/include/uapi/linux/fs.h |
| @@ -201,6 +201,13 @@ struct fsxattr { |
| |
| #define FSLABEL_MAX 256 /* Max chars for the interface; each fs may differ */ |
| |
| +/* |
| + * This IOCTL has been added as a workaround for cryptohome to clear |
| + * cached unencrypted user data on logout. |
| + * Drop caches for a superblock |
| + */ |
| +#define FS_IOC_DROP_CACHE _IO('f', 129) |
| + |
| #define FS_IOC_GETFLAGS _IOR('f', 1, long) |
| #define FS_IOC_SETFLAGS _IOW('f', 2, long) |
| #define FS_IOC_GETVERSION _IOR('v', 1, long) |
| -- |
| 2.31.1.818.g46aad6cb9e-goog |
| |