ext4: add a new ioctl EXT4_IOC_GETSTATE
authorTheodore Ts'o <tytso@mit.edu>
Sun, 11 Aug 2019 20:31:41 +0000 (16:31 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Sun, 11 Aug 2019 20:31:41 +0000 (16:31 -0400)
The new ioctl EXT4_IOC_GETSTATE returns some of the dynamic state of
an ext4 inode for debugging purposes.

Signed-off-by: Theodore Ts'o <tytso@mit.edu>
fs/ext4/ext4.h
fs/ext4/ioctl.c

index b22f24f1d365d9a252836775cc048492bc2a542b..ee296797bcd28254f00f9484894860cca7b7149d 100644 (file)
@@ -651,6 +651,7 @@ enum {
 #define EXT4_IOC_GET_ENCRYPTION_POLICY FS_IOC_GET_ENCRYPTION_POLICY
 /* ioctl codes 19--39 are reserved for fscrypt */
 #define EXT4_IOC_CLEAR_ES_CACHE                _IO('f', 40)
+#define EXT4_IOC_GETSTATE              _IOW('f', 41, __u32)
 
 #define EXT4_IOC_FSGETXATTR            FS_IOC_FSGETXATTR
 #define EXT4_IOC_FSSETXATTR            FS_IOC_FSSETXATTR
@@ -664,6 +665,16 @@ enum {
 #define EXT4_GOING_FLAGS_LOGFLUSH              0x1     /* flush log but not data */
 #define EXT4_GOING_FLAGS_NOLOGFLUSH            0x2     /* don't flush log nor data */
 
+/*
+ * Flags returned by EXT4_IOC_GETSTATE
+ *
+ * We only expose to userspace a subset of the state flags in
+ * i_state_flags
+ */
+#define EXT4_STATE_FLAG_EXT_PRECACHED  0x00000001
+#define EXT4_STATE_FLAG_NEW            0x00000002
+#define EXT4_STATE_FLAG_NEWENTRY       0x00000004
+#define EXT4_STATE_FLAG_DA_ALLOC_CLOSE 0x00000008
 
 #if defined(__KERNEL__) && defined(CONFIG_COMPAT)
 /*
index 15b1047878ab3ccba1d40b8692c1c5d48d7ae60d..ffb7bde4900d26a5acb57d0e7f4d14ea3ec2934c 100644 (file)
@@ -1123,6 +1123,22 @@ resizefs_out:
                return 0;
        }
 
+       case EXT4_IOC_GETSTATE:
+       {
+               __u32   state = 0;
+
+               if (ext4_test_inode_state(inode, EXT4_STATE_EXT_PRECACHED))
+                       state |= EXT4_STATE_FLAG_EXT_PRECACHED;
+               if (ext4_test_inode_state(inode, EXT4_STATE_NEW))
+                       state |= EXT4_STATE_FLAG_NEW;
+               if (ext4_test_inode_state(inode, EXT4_STATE_NEWENTRY))
+                       state |= EXT4_STATE_FLAG_NEWENTRY;
+               if (ext4_test_inode_state(inode, EXT4_STATE_DA_ALLOC_CLOSE))
+                       state |= EXT4_STATE_FLAG_DA_ALLOC_CLOSE;
+
+               return put_user(state, (__u32 __user *) arg);
+       }
+
        case EXT4_IOC_FSGETXATTR:
        {
                struct fsxattr fa;
@@ -1242,6 +1258,7 @@ long ext4_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
        case EXT4_IOC_SHUTDOWN:
        case FS_IOC_GETFSMAP:
        case EXT4_IOC_CLEAR_ES_CACHE:
+       case EXT4_IOC_GETSTATE:
                break;
        default:
                return -ENOIOCTLCMD;