blob: 85103030ce17b7d2b271fe4d0842ae238ea4fa10 [file] [log] [blame]
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