[Devel] [PATCH RHEL7 COMMIT] ext4: add a new ioctl EXT4_IOC_CLEAR_ES_CACHE
Vasily Averin
vvs at virtuozzo.com
Mon Aug 17 09:52:37 MSK 2020
The commit is pushed to "branch-rh7-3.10.0-1127.18.2.vz7.163.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-1127.18.2.vz7.163.2
------>
commit ea05de712cfc226de2a0f75bc18c1879871f08f2
Author: Theodore Ts'o <tytso at mit.edu>
Date: Mon Aug 17 09:52:37 2020 +0300
ext4: add a new ioctl EXT4_IOC_CLEAR_ES_CACHE
ms commit b0c013e2928d
The new ioctl EXT4_IOC_CLEAR_ES_CACHE will force an inode's extent
status cache to be cleared out. This is intended for use for
debugging.
https://jira.sw.ru/browse/PSBM-105347
Signed-off-by: Theodore Ts'o <tytso at mit.edu>
ext4_fiemap() on 3.10 uses information from cached extent tree
only for checks of delayed extent status, while every of
the checks waste much time iterating over all extents in tree
(many rb_next). We will use this ioctl before filefrag (which
populates the tree from start to end of file, so every iteration
rb_next() path is rather short).
Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
---
fs/ext4/ext4.h | 2 ++
fs/ext4/extents_status.c | 28 ++++++++++++++++++++++++++++
fs/ext4/extents_status.h | 2 ++
fs/ext4/ioctl.c | 9 +++++++++
4 files changed, 41 insertions(+)
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 7eda9c3..9202c5e 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -624,6 +624,8 @@ enum {
#define EXT4_IOC_RESIZE_FS _IOW('f', 16, __u64)
#define EXT4_IOC_SWAP_BOOT _IO('f', 17)
#define EXT4_IOC_PRECACHE_EXTENTS _IO('f', 18)
+/* ioctl codes 19--39 are reserved for fscrypt */
+#define EXT4_IOC_CLEAR_ES_CACHE _IO('f', 40)
#define EXT4_IOC_OPEN_BALLOON _IO('f', 42)
#define EXT4_IOC_MFSYNC _IO('f', 43)
#define EXT4_IOC_SET_RSV_BLOCKS _IOW('f', 44, __u64)
diff --git a/fs/ext4/extents_status.c b/fs/ext4/extents_status.c
index d8dcc42..d78546e 100644
--- a/fs/ext4/extents_status.c
+++ b/fs/ext4/extents_status.c
@@ -1166,3 +1166,31 @@ static int es_reclaim_extents(struct ext4_inode_info *ei, int *nr_to_scan)
ei->i_es_tree.cache_es = NULL;
return nr_shrunk;
}
+
+/*
+ * Called to support EXT4_IOC_CLEAR_ES_CACHE. We can only remove
+ * discretionary entries from the extent status cache. (Some entries
+ * must be present for proper operations.)
+ */
+void ext4_clear_inode_es(struct inode *inode)
+{
+ struct ext4_inode_info *ei = EXT4_I(inode);
+ struct extent_status *es;
+ struct ext4_es_tree *tree;
+ struct rb_node *node;
+
+ write_lock(&ei->i_es_lock);
+ tree = &EXT4_I(inode)->i_es_tree;
+ tree->cache_es = NULL;
+ node = rb_first(&tree->root);
+ while (node) {
+ es = rb_entry(node, struct extent_status, rb_node);
+ node = rb_next(node);
+ if (!ext4_es_is_delayed(es)) {
+ rb_erase(&es->rb_node, &tree->root);
+ ext4_es_free_extent(inode, es);
+ }
+ }
+ ext4_clear_inode_state(inode, EXT4_STATE_EXT_PRECACHED);
+ write_unlock(&ei->i_es_lock);
+}
diff --git a/fs/ext4/extents_status.h b/fs/ext4/extents_status.h
index 0b85145..2b08c4c 100644
--- a/fs/ext4/extents_status.h
+++ b/fs/ext4/extents_status.h
@@ -168,4 +168,6 @@ static inline void ext4_es_store_pblock_status(struct extent_status *es,
extern int ext4_es_register_shrinker(struct ext4_sb_info *sbi);
extern void ext4_es_unregister_shrinker(struct ext4_sb_info *sbi);
+extern void ext4_clear_inode_es(struct inode *inode);
+
#endif /* _EXT4_EXTENTS_STATUS_H */
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
index a50016a..3356a5e 100644
--- a/fs/ext4/ioctl.c
+++ b/fs/ext4/ioctl.c
@@ -754,6 +754,14 @@ resize_out:
case EXT4_IOC_PRECACHE_EXTENTS:
return ext4_ext_precache(inode);
+ case EXT4_IOC_CLEAR_ES_CACHE:
+ {
+ if (!inode_owner_or_capable(inode))
+ return -EACCES;
+ ext4_clear_inode_es(inode);
+ return 0;
+ }
+
case EXT4_IOC_OPEN_BALLOON:
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
@@ -912,6 +920,7 @@ long ext4_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
case FITRIM:
case EXT4_IOC_RESIZE_FS:
case EXT4_IOC_PRECACHE_EXTENTS:
+ case EXT4_IOC_CLEAR_ES_CACHE:
break;
case FS_IOC_PFCACHE_OPEN:
case FS_IOC_PFCACHE_CLOSE:
More information about the Devel
mailing list