[3/3] ext4: add a new ioctl EXT4_IOC_GETSTATE
diff mbox series

Message ID 20190809181831.10618-3-tytso@mit.edu
State Superseded
Headers show
Series
  • [1/3] ext4: return the extent cache information via fiemap
Related show

Commit Message

Theodore Y. Ts'o Aug. 9, 2019, 6:18 p.m. UTC
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  | 11 +++++++++++
 fs/ext4/ioctl.c | 17 +++++++++++++++++
 2 files changed, 28 insertions(+)

Comments

Eric Biggers Aug. 9, 2019, 7:18 p.m. UTC | #1
On Fri, Aug 09, 2019 at 02:18:31PM -0400, Theodore Ts'o wrote:
> 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  | 11 +++++++++++
>  fs/ext4/ioctl.c | 17 +++++++++++++++++
>  2 files changed, 28 insertions(+)
> 
> diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
> index f6c305b43ffa..58b7a0905186 100644
> --- a/fs/ext4/ext4.h
> +++ b/fs/ext4/ext4.h
> @@ -651,6 +651,7 @@ enum {
>  #define EXT4_IOC_GET_ENCRYPTION_POLICY	FS_IOC_GET_ENCRYPTION_POLICY
>  /* ioctl codes 19--2F are reserved for fscrypt */
>  #define EXT4_IOC_CLEAR_ES_CACHE		_IO('f', 30)
> +#define EXT4_IOC_GETSTATE		_IOW('f', 30, __u32)

30 == 0x1e overlaps with the range claimed to be reserved for fscrypt.

Also, these two new ioctls are both number 30, which means they can't be
controlled separately by SELinux, which only looks at the number.

- Eric
Theodore Y. Ts'o Aug. 10, 2019, 12:12 a.m. UTC | #2
On Fri, Aug 09, 2019 at 12:18:12PM -0700, Eric Biggers wrote:
> On Fri, Aug 09, 2019 at 02:18:31PM -0400, Theodore Ts'o wrote:
> > 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  | 11 +++++++++++
> >  fs/ext4/ioctl.c | 17 +++++++++++++++++
> >  2 files changed, 28 insertions(+)
> > 
> > diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
> > index f6c305b43ffa..58b7a0905186 100644
> > --- a/fs/ext4/ext4.h
> > +++ b/fs/ext4/ext4.h
> > @@ -651,6 +651,7 @@ enum {
> >  #define EXT4_IOC_GET_ENCRYPTION_POLICY	FS_IOC_GET_ENCRYPTION_POLICY
> >  /* ioctl codes 19--2F are reserved for fscrypt */
> >  #define EXT4_IOC_CLEAR_ES_CACHE		_IO('f', 30)
> > +#define EXT4_IOC_GETSTATE		_IOW('f', 30, __u32)
> 
> 30 == 0x1e overlaps with the range claimed to be reserved for fscrypt.
> 
> Also, these two new ioctls are both number 30, which means they can't be
> controlled separately by SELinux, which only looks at the number.

Yeah, that was my screw up.  The range reservation for fscrypt was
intended to be in decimal starting with 19 decimal
(FSIOC_SET_ENCRYPTION_POLICY), and I believe with the new key
management we were up to 26?  So If I reserve up to 39, that should be
more than enough, do you agree?

I'll then make EXT4_IOC_CLEAR_ES_CACHE 40 and EXT4_IOC_GETSTATE 41.

If we're in agreement, then I'll add an update to
Documentation/ioctl/ioctl-number.rst, which is badly out of date with
respect to the ioctl's used in ext2 and ext4 (and of course ext3 has
since been removed from the kernel tree).

						- Ted
Eric Biggers Aug. 11, 2019, 9:38 p.m. UTC | #3
On Fri, Aug 09, 2019 at 08:12:47PM -0400, Theodore Y. Ts'o wrote:
> On Fri, Aug 09, 2019 at 12:18:12PM -0700, Eric Biggers wrote:
> > On Fri, Aug 09, 2019 at 02:18:31PM -0400, Theodore Ts'o wrote:
> > > 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  | 11 +++++++++++
> > >  fs/ext4/ioctl.c | 17 +++++++++++++++++
> > >  2 files changed, 28 insertions(+)
> > > 
> > > diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
> > > index f6c305b43ffa..58b7a0905186 100644
> > > --- a/fs/ext4/ext4.h
> > > +++ b/fs/ext4/ext4.h
> > > @@ -651,6 +651,7 @@ enum {
> > >  #define EXT4_IOC_GET_ENCRYPTION_POLICY	FS_IOC_GET_ENCRYPTION_POLICY
> > >  /* ioctl codes 19--2F are reserved for fscrypt */
> > >  #define EXT4_IOC_CLEAR_ES_CACHE		_IO('f', 30)
> > > +#define EXT4_IOC_GETSTATE		_IOW('f', 30, __u32)
> > 
> > 30 == 0x1e overlaps with the range claimed to be reserved for fscrypt.
> > 
> > Also, these two new ioctls are both number 30, which means they can't be
> > controlled separately by SELinux, which only looks at the number.
> 
> Yeah, that was my screw up.  The range reservation for fscrypt was
> intended to be in decimal starting with 19 decimal
> (FSIOC_SET_ENCRYPTION_POLICY), and I believe with the new key
> management we were up to 26?  So If I reserve up to 39, that should be
> more than enough, do you agree?
> 
> I'll then make EXT4_IOC_CLEAR_ES_CACHE 40 and EXT4_IOC_GETSTATE 41.
> 
> If we're in agreement, then I'll add an update to
> Documentation/ioctl/ioctl-number.rst, which is badly out of date with
> respect to the ioctl's used in ext2 and ext4 (and of course ext3 has
> since been removed from the kernel tree).
> 

Sounds good to me.

- Eric

Patch
diff mbox series

diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index f6c305b43ffa..58b7a0905186 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -651,6 +651,7 @@  enum {
 #define EXT4_IOC_GET_ENCRYPTION_POLICY	FS_IOC_GET_ENCRYPTION_POLICY
 /* ioctl codes 19--2F are reserved for fscrypt */
 #define EXT4_IOC_CLEAR_ES_CACHE		_IO('f', 30)
+#define EXT4_IOC_GETSTATE		_IOW('f', 30, __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)
 /*
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
index 15b1047878ab..ffb7bde4900d 100644
--- a/fs/ext4/ioctl.c
+++ b/fs/ext4/ioctl.c
@@ -1123,6 +1123,22 @@  long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 		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;