Linux-ext4 Archive on lore.kernel.org
 help / color / Atom feed
* Exporting ext4-specific information through fsinfo attributes
@ 2020-04-01  7:39 David Howells
  2020-04-01 15:18 ` Darrick J. Wong
                   ` (2 more replies)
  0 siblings, 3 replies; 15+ messages in thread
From: David Howells @ 2020-04-01  7:39 UTC (permalink / raw)
  To: tytso; +Cc: dhowells, adilger.kernel, linux-ext4

Hi Ted,

Whilst we were at Vault, I asked you if there was any live ext4 information
that it could be useful to export through fsinfo().  I've implemented a patch
that exports six superblock timestamps:

	FSINFO_ATTR_EXT4_TIMESTAMPS: 
		mkfs    : 2016-02-26 00:37:03
		mount   : 2020-03-31 21:57:30
		write   : 2020-03-31 21:57:28
		fsck    : 2018-12-17 23:32:45
		1st-err : -
		last-err: -

but is there anything else that could be of interest?

Thanks,
David


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Exporting ext4-specific information through fsinfo attributes
  2020-04-01  7:39 Exporting ext4-specific information through fsinfo attributes David Howells
@ 2020-04-01 15:18 ` Darrick J. Wong
  2020-04-01 16:27 ` Eric Biggers
  2020-04-21 16:17 ` David Howells
  2 siblings, 0 replies; 15+ messages in thread
From: Darrick J. Wong @ 2020-04-01 15:18 UTC (permalink / raw)
  To: David Howells; +Cc: tytso, adilger.kernel, linux-ext4

On Wed, Apr 01, 2020 at 08:39:07AM +0100, David Howells wrote:
> Hi Ted,
> 
> Whilst we were at Vault, I asked you if there was any live ext4 information
> that it could be useful to export through fsinfo().  I've implemented a patch
> that exports six superblock timestamps:
> 
> 	FSINFO_ATTR_EXT4_TIMESTAMPS: 
> 		mkfs    : 2016-02-26 00:37:03
> 		mount   : 2020-03-31 21:57:30
> 		write   : 2020-03-31 21:57:28
> 		fsck    : 2018-12-17 23:32:45
> 		1st-err : -
> 		last-err: -
> 
> but is there anything else that could be of interest?

The entire superblock as a binary blob? :)

This way we can begin moving dumpe2fs/tune2fs away from reading the raw
disk on live filesystems.

(I'd make the same noises about xfs, but less urgently since we already
have ioctls for that purpose.)

--D

> 
> Thanks,
> David
> 

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Exporting ext4-specific information through fsinfo attributes
  2020-04-01  7:39 Exporting ext4-specific information through fsinfo attributes David Howells
  2020-04-01 15:18 ` Darrick J. Wong
@ 2020-04-01 16:27 ` Eric Biggers
  2020-04-01 19:05   ` Darrick J. Wong
  2020-04-21 16:17 ` David Howells
  2 siblings, 1 reply; 15+ messages in thread
From: Eric Biggers @ 2020-04-01 16:27 UTC (permalink / raw)
  To: David Howells; +Cc: tytso, adilger.kernel, linux-ext4

On Wed, Apr 01, 2020 at 08:39:07AM +0100, David Howells wrote:
> Hi Ted,
> 
> Whilst we were at Vault, I asked you if there was any live ext4 information
> that it could be useful to export through fsinfo().  I've implemented a patch
> that exports six superblock timestamps:
> 
> 	FSINFO_ATTR_EXT4_TIMESTAMPS: 
> 		mkfs    : 2016-02-26 00:37:03
> 		mount   : 2020-03-31 21:57:30
> 		write   : 2020-03-31 21:57:28
> 		fsck    : 2018-12-17 23:32:45
> 		1st-err : -
> 		last-err: -
> 
> but is there anything else that could be of interest?
> 
> Thanks,
> David
> 

FWIW, the filesystem UUID would be useful for testing ext4 and f2fs encryption
(since it's now sometimes used in the derivation of encryption keys).  But I see
you already included it as FSINFO_ATTR_VOLUME_UUID.

- Eric

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Exporting ext4-specific information through fsinfo attributes
  2020-04-01 16:27 ` Eric Biggers
@ 2020-04-01 19:05   ` Darrick J. Wong
  2020-04-01 19:28     ` Eric Biggers
  0 siblings, 1 reply; 15+ messages in thread
From: Darrick J. Wong @ 2020-04-01 19:05 UTC (permalink / raw)
  To: Eric Biggers; +Cc: David Howells, tytso, adilger.kernel, linux-ext4

On Wed, Apr 01, 2020 at 09:27:44AM -0700, Eric Biggers wrote:
> On Wed, Apr 01, 2020 at 08:39:07AM +0100, David Howells wrote:
> > Hi Ted,
> > 
> > Whilst we were at Vault, I asked you if there was any live ext4 information
> > that it could be useful to export through fsinfo().  I've implemented a patch
> > that exports six superblock timestamps:
> > 
> > 	FSINFO_ATTR_EXT4_TIMESTAMPS: 
> > 		mkfs    : 2016-02-26 00:37:03
> > 		mount   : 2020-03-31 21:57:30
> > 		write   : 2020-03-31 21:57:28
> > 		fsck    : 2018-12-17 23:32:45
> > 		1st-err : -
> > 		last-err: -
> > 
> > but is there anything else that could be of interest?
> > 
> > Thanks,
> > David
> > 
> 
> FWIW, the filesystem UUID would be useful for testing ext4 and f2fs encryption
> (since it's now sometimes used in the derivation of encryption keys).  But I see
> you already included it as FSINFO_ATTR_VOLUME_UUID.

It is??  What happens if you tune2fs -U if csum_seed isn't enabled?

--D

> 
> - Eric

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Exporting ext4-specific information through fsinfo attributes
  2020-04-01 19:05   ` Darrick J. Wong
@ 2020-04-01 19:28     ` Eric Biggers
  2020-04-01 20:36       ` Eric Biggers
  0 siblings, 1 reply; 15+ messages in thread
From: Eric Biggers @ 2020-04-01 19:28 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: David Howells, tytso, adilger.kernel, linux-ext4

On Wed, Apr 01, 2020 at 12:05:53PM -0700, Darrick J. Wong wrote:
> On Wed, Apr 01, 2020 at 09:27:44AM -0700, Eric Biggers wrote:
> > On Wed, Apr 01, 2020 at 08:39:07AM +0100, David Howells wrote:
> > > Hi Ted,
> > > 
> > > Whilst we were at Vault, I asked you if there was any live ext4 information
> > > that it could be useful to export through fsinfo().  I've implemented a patch
> > > that exports six superblock timestamps:
> > > 
> > > 	FSINFO_ATTR_EXT4_TIMESTAMPS: 
> > > 		mkfs    : 2016-02-26 00:37:03
> > > 		mount   : 2020-03-31 21:57:30
> > > 		write   : 2020-03-31 21:57:28
> > > 		fsck    : 2018-12-17 23:32:45
> > > 		1st-err : -
> > > 		last-err: -
> > > 
> > > but is there anything else that could be of interest?
> > > 
> > > Thanks,
> > > David
> > > 
> > 
> > FWIW, the filesystem UUID would be useful for testing ext4 and f2fs encryption
> > (since it's now sometimes used in the derivation of encryption keys).  But I see
> > you already included it as FSINFO_ATTR_VOLUME_UUID.
> 
> It is??  What happens if you tune2fs -U if csum_seed isn't enabled?
> 

It's only used for IV_INO_LBLK_64 encryption policies, which include the inode
number in the IVs.  The UUID had to be used to distinguish the same inode number
on multiple filesystems, in case the same key is used on multiple filesystems.

Since this type of encryption policy also requires stable inode numbers, on ext4
it can only be set if user has run 'tune2fs -O stable_inodes' to also prevent
filesystem shrinking.

I didn't know that e2fsprogs had a supported way to change the filesystem UUID.
We maybe should make tune2fs -U refuse to operate on filesystems that have the
stable_inodes feature set.  However, the chance that someone would actually
break their encrypted files by changing their filesystem UUID is pretty low,
since most users use the normal fscrypt policies instead.  IV_INO_LBLK_64 is
only really useful with UFS inline encryption hardware, and systems with this
hardware aren't the type of systems you can just log into and randomly change
your filesystem UUID.  For standard Linux distros we have a tool
https://github.com/google/fscrypt, but it doesn't support IV_INO_LBLK_64 yet.

- Eric

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Exporting ext4-specific information through fsinfo attributes
  2020-04-01 19:28     ` Eric Biggers
@ 2020-04-01 20:36       ` Eric Biggers
  0 siblings, 0 replies; 15+ messages in thread
From: Eric Biggers @ 2020-04-01 20:36 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: David Howells, tytso, adilger.kernel, linux-ext4

On Wed, Apr 01, 2020 at 12:28:40PM -0700, Eric Biggers wrote:
> We maybe should make tune2fs -U refuse to operate on filesystems that have the
> stable_inodes feature set.

I sent patches to do this and clean up a few other things:

https://lkml.kernel.org/linux-ext4/20200401203239.163679-1-ebiggers@kernel.org

- Eric

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Exporting ext4-specific information through fsinfo attributes
  2020-04-01  7:39 Exporting ext4-specific information through fsinfo attributes David Howells
  2020-04-01 15:18 ` Darrick J. Wong
  2020-04-01 16:27 ` Eric Biggers
@ 2020-04-21 16:17 ` David Howells
  2020-04-21 22:07   ` Andreas Dilger
                     ` (3 more replies)
  2 siblings, 4 replies; 15+ messages in thread
From: David Howells @ 2020-04-21 16:17 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: dhowells, Eric Biggers, tytso, adilger.kernel, linux-ext4

Darrick J. Wong <darrick.wong@oracle.com> wrote:

> The entire superblock as a binary blob? :)

How about the attached?  Please forgive the duplication of struct
ext4_super_block into the test program, but it's not in the UAPI.

David
---
fsinfo: Add support to ext4
    
Add support to ext4, including the following:

 (1) FSINFO_ATTR_SUPPORTS: Information about supported STATX attributes and
     support for ioctls like FS_IOC_[GS]ETFLAGS and FS_IOC_FS[GS]ETXATTR.

 (2) FSINFO_ATTR_FEATURES: Information about features supported by an ext4
     filesystem, such as whether version counting, birth time and name case
     folding are in operation.

 (3) FSINFO_ATTR_VOLUME_NAME: The volume name from the superblock.

 (4) FSINFO_ATTR_EXT4_SUPERBLOCK: The entirety of the on disk-format
     superblock record as an opaque blob.

Signed-off-by: David Howells <dhowells@redhat.com>
cc: "Theodore Ts'o" <tytso@mit.edu>
cc: Andreas Dilger <adilger.kernel@dilger.ca>
cc: "Darrick J. Wong" <darrick.wong@oracle.com>
cc: Eric Biggers <ebiggers@kernel.org>
cc: linux-ext4@vger.kernel.org
---
 fs/ext4/Makefile            |    1 
 fs/ext4/ext4.h              |    6 +
 fs/ext4/fsinfo.c            |  106 ++++++++++++++++++++++++++++++++
 fs/ext4/super.c             |    3 
 include/uapi/linux/fsinfo.h |    2 
 samples/vfs/test-fsinfo.c   |  143 ++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 261 insertions(+)


diff --git a/fs/ext4/Makefile b/fs/ext4/Makefile
index 4ccb3c9189d8..71d5b460c7c7 100644
--- a/fs/ext4/Makefile
+++ b/fs/ext4/Makefile
@@ -16,3 +16,4 @@ ext4-$(CONFIG_EXT4_FS_SECURITY)		+= xattr_security.o
 ext4-inode-test-objs			+= inode-test.o
 obj-$(CONFIG_EXT4_KUNIT_TESTS)		+= ext4-inode-test.o
 ext4-$(CONFIG_FS_VERITY)		+= verity.o
+ext4-$(CONFIG_FSINFO)			+= fsinfo.o
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 91eb4381cae5..674581da786c 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -42,6 +42,7 @@
 
 #include <linux/fscrypt.h>
 #include <linux/fsverity.h>
+#include <linux/fsinfo.h>
 
 #include <linux/compiler.h>
 
@@ -3207,6 +3208,11 @@ extern const struct inode_operations ext4_file_inode_operations;
 extern const struct file_operations ext4_file_operations;
 extern loff_t ext4_llseek(struct file *file, loff_t offset, int origin);
 
+/* fsinfo.c */
+#ifdef CONFIG_FSINFO
+extern int ext4_fsinfo(struct path *path, struct fsinfo_context *ctx);
+#endif
+
 /* inline.c */
 extern int ext4_get_max_inline_size(struct inode *inode);
 extern int ext4_find_inline_data_nolock(struct inode *inode);
diff --git a/fs/ext4/fsinfo.c b/fs/ext4/fsinfo.c
new file mode 100644
index 000000000000..52bfd09e550f
--- /dev/null
+++ b/fs/ext4/fsinfo.c
@@ -0,0 +1,106 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Filesystem information for ext4
+ *
+ * Copyright (C) 2020 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ */
+
+#include <linux/mount.h>
+#include "ext4.h"
+
+static int ext4_fsinfo_supports(struct path *path, struct fsinfo_context *ctx)
+{
+	struct fsinfo_supports *p = ctx->buffer;
+	struct inode *inode = d_inode(path->dentry);
+	struct ext4_inode_info *ei = EXT4_I(inode);
+	struct ext4_inode *raw_inode;
+	u32 flags;
+
+	fsinfo_generic_supports(path, ctx);
+	p->stx_attributes |= (STATX_ATTR_APPEND |
+			      STATX_ATTR_COMPRESSED |
+			      STATX_ATTR_ENCRYPTED |
+			      STATX_ATTR_IMMUTABLE |
+			      STATX_ATTR_NODUMP |
+			      STATX_ATTR_VERITY);
+	if (EXT4_FITS_IN_INODE(raw_inode, ei, i_crtime))
+		p->stx_mask |= STATX_BTIME;
+
+	flags = EXT4_FL_USER_VISIBLE;
+	if (S_ISREG(inode->i_mode))
+		flags &= ~EXT4_PROJINHERIT_FL;
+	p->fs_ioc_getflags = flags;
+	flags &= EXT4_FL_USER_MODIFIABLE;
+	p->fs_ioc_setflags_set = flags;
+	p->fs_ioc_setflags_clear = flags;
+
+	p->fs_ioc_fsgetxattr_xflags = EXT4_FL_XFLAG_VISIBLE;
+	p->fs_ioc_fssetxattr_xflags_set = EXT4_FL_XFLAG_VISIBLE;
+	p->fs_ioc_fssetxattr_xflags_clear = EXT4_FL_XFLAG_VISIBLE;
+	return sizeof(*p);
+}
+
+static int ext4_fsinfo_features(struct path *path, struct fsinfo_context *ctx)
+{
+	struct fsinfo_features *p = ctx->buffer;
+	struct super_block *sb = path->dentry->d_sb;
+	struct inode *inode = d_inode(path->dentry);
+	struct ext4_inode_info *ei = EXT4_I(inode);
+	struct ext4_inode *raw_inode;
+
+	fsinfo_generic_features(path, ctx);
+	fsinfo_set_unix_features(p);
+	fsinfo_set_feature(p, FSINFO_FEAT_VOLUME_UUID);
+	fsinfo_set_feature(p, FSINFO_FEAT_VOLUME_NAME);
+	fsinfo_set_feature(p, FSINFO_FEAT_O_SYNC);
+	fsinfo_set_feature(p, FSINFO_FEAT_O_DIRECT);
+	fsinfo_set_feature(p, FSINFO_FEAT_ADV_LOCKS);
+
+	if (test_opt(sb, XATTR_USER))
+		fsinfo_set_feature(p, FSINFO_FEAT_XATTRS);
+	if (ext4_has_feature_journal(sb))
+		fsinfo_set_feature(p, FSINFO_FEAT_JOURNAL);
+	if (ext4_has_feature_casefold(sb))
+		fsinfo_set_feature(p, FSINFO_FEAT_NAME_CASE_INDEP);
+
+	if (sb->s_flags & SB_I_VERSION &&
+	    !test_opt2(sb, HURD_COMPAT) &&
+	    EXT4_INODE_SIZE(sb) > EXT4_GOOD_OLD_INODE_SIZE) {
+		fsinfo_set_feature(p, FSINFO_FEAT_IVER_DATA_CHANGE);
+		fsinfo_set_feature(p, FSINFO_FEAT_IVER_MONO_INCR);
+	}
+
+	if (EXT4_FITS_IN_INODE(raw_inode, ei, i_crtime))
+		fsinfo_set_feature(p, FSINFO_FEAT_HAS_BTIME);
+	return sizeof(*p);
+}
+
+static int ext4_fsinfo_get_volume_name(struct path *path, struct fsinfo_context *ctx)
+{
+	const struct ext4_sb_info *sbi = EXT4_SB(path->mnt->mnt_sb);
+	const struct ext4_super_block *es = sbi->s_es;
+
+	memcpy(ctx->buffer, es->s_volume_name, sizeof(es->s_volume_name));
+	return strlen(ctx->buffer) + 1;
+}
+
+static int ext4_fsinfo_get_superblock(struct path *path, struct fsinfo_context *ctx)
+{
+	const struct ext4_sb_info *sbi = EXT4_SB(path->mnt->mnt_sb);
+	const struct ext4_super_block *es = sbi->s_es;
+
+	return fsinfo_opaque(es, ctx, sizeof(*es));
+}
+
+static const struct fsinfo_attribute ext4_fsinfo_attributes[] = {
+	FSINFO_VSTRUCT	(FSINFO_ATTR_SUPPORTS,		ext4_fsinfo_supports),
+	FSINFO_VSTRUCT	(FSINFO_ATTR_FEATURES,		ext4_fsinfo_features),
+	FSINFO_STRING	(FSINFO_ATTR_VOLUME_NAME,	ext4_fsinfo_get_volume_name),
+	FSINFO_OPAQUE	(FSINFO_ATTR_EXT4_SUPERBLOCK,	ext4_fsinfo_get_superblock),
+	{}
+};
+
+int ext4_fsinfo(struct path *path, struct fsinfo_context *ctx)
+{
+	return fsinfo_get_attribute(path, ctx, ext4_fsinfo_attributes);
+}
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index bf5fcb477f66..201287a90c4b 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -1482,6 +1482,9 @@ static const struct super_operations ext4_sops = {
 	.freeze_fs	= ext4_freeze,
 	.unfreeze_fs	= ext4_unfreeze,
 	.statfs		= ext4_statfs,
+#ifdef CONFIG_FSINFO
+	.fsinfo		= ext4_fsinfo,
+#endif
 	.remount_fs	= ext4_remount,
 	.show_options	= ext4_show_options,
 #ifdef CONFIG_QUOTA
diff --git a/include/uapi/linux/fsinfo.h b/include/uapi/linux/fsinfo.h
index 3483dd9a5d05..51214c0c82b1 100644
--- a/include/uapi/linux/fsinfo.h
+++ b/include/uapi/linux/fsinfo.h
@@ -42,6 +42,8 @@
 #define FSINFO_ATTR_AFS_SERVER_NAME	0x301	/* Name of the Nth server (string) */
 #define FSINFO_ATTR_AFS_SERVER_ADDRESSES 0x302	/* List of addresses of the Nth server */
 
+#define FSINFO_ATTR_EXT4_SUPERBLOCK	0x400	/* Ext4 superblock (opaque) */
+
 /*
  * Optional fsinfo() parameter structure.
  *
diff --git a/samples/vfs/test-fsinfo.c b/samples/vfs/test-fsinfo.c
index 4c6f3f1002dd..a6dacc2ec59d 100644
--- a/samples/vfs/test-fsinfo.c
+++ b/samples/vfs/test-fsinfo.c
@@ -24,6 +24,7 @@
 #include <sys/stat.h>
 #include <arpa/inet.h>
 #include <linux/rxrpc.h>
+#include <linux/byteorder/little_endian.h>
 
 #ifndef __NR_fsinfo
 #define __NR_fsinfo -1
@@ -389,6 +390,147 @@ static void dump_afs_fsinfo_server_address(void *reply, unsigned int size)
 	printf("family=%u\n", ss->ss_family);
 }
 
+static char *dump_ext4_time(char *buffer, time_t tim)
+{
+	struct tm tm;
+	int len;
+
+	if (tim == 0)
+		return "-";
+
+	if (!localtime_r(&tim, &tm)) {
+		perror("localtime_r");
+		exit(1);
+	}
+	len = strftime(buffer, 100, "%F %T", &tm);
+	if (len == 0) {
+		perror("strftime");
+		exit(1);
+	}
+	return buffer;
+}
+
+static void dump_ext4_fsinfo_superblock(void *reply, unsigned int size)
+{
+	struct ext4_super_block {
+	/*00*/	__le32	s_inodes_count;		/* Inodes count */
+		__le32	s_blocks_count_lo;	/* Blocks count */
+		__le32	s_r_blocks_count_lo;	/* Reserved blocks count */
+		__le32	s_free_blocks_count_lo;	/* Free blocks count */
+	/*10*/	__le32	s_free_inodes_count;	/* Free inodes count */
+		__le32	s_first_data_block;	/* First Data Block */
+		__le32	s_log_block_size;	/* Block size */
+		__le32	s_log_cluster_size;	/* Allocation cluster size */
+	/*20*/	__le32	s_blocks_per_group;	/* # Blocks per group */
+		__le32	s_clusters_per_group;	/* # Clusters per group */
+		__le32	s_inodes_per_group;	/* # Inodes per group */
+		__le32	s_mtime;		/* Mount time */
+	/*30*/	__le32	s_wtime;		/* Write time */
+		__le16	s_mnt_count;		/* Mount count */
+		__le16	s_max_mnt_count;	/* Maximal mount count */
+		__le16	s_magic;		/* Magic signature */
+		__le16	s_state;		/* File system state */
+		__le16	s_errors;		/* Behaviour when detecting errors */
+		__le16	s_minor_rev_level;	/* minor revision level */
+	/*40*/	__le32	s_lastcheck;		/* time of last check */
+		__le32	s_checkinterval;	/* max. time between checks */
+		__le32	s_creator_os;		/* OS */
+		__le32	s_rev_level;		/* Revision level */
+	/*50*/	__le16	s_def_resuid;		/* Default uid for reserved blocks */
+		__le16	s_def_resgid;		/* Default gid for reserved blocks */
+		__le32	s_first_ino;		/* First non-reserved inode */
+		__le16  s_inode_size;		/* size of inode structure */
+		__le16	s_block_group_nr;	/* block group # of this superblock */
+		__le32	s_feature_compat;	/* compatible feature set */
+	/*60*/	__le32	s_feature_incompat;	/* incompatible feature set */
+		__le32	s_feature_ro_compat;	/* readonly-compatible feature set */
+	/*68*/	__u8	s_uuid[16];		/* 128-bit uuid for volume */
+	/*78*/	char	s_volume_name[16];	/* volume name */
+	/*88*/	char	s_last_mounted[64];	/* directory where last mounted */
+	/*C8*/	__le32	s_algorithm_usage_bitmap; /* For compression */
+		__u8	s_prealloc_blocks;	/* Nr of blocks to try to preallocate*/
+		__u8	s_prealloc_dir_blocks;	/* Nr to preallocate for dirs */
+		__le16	s_reserved_gdt_blocks;	/* Per group desc for online growth */
+	/*D0*/	__u8	s_journal_uuid[16];	/* uuid of journal superblock */
+	/*E0*/	__le32	s_journal_inum;		/* inode number of journal file */
+		__le32	s_journal_dev;		/* device number of journal file */
+		__le32	s_last_orphan;		/* start of list of inodes to delete */
+		__le32	s_hash_seed[4];		/* HTREE hash seed */
+		__u8	s_def_hash_version;	/* Default hash version to use */
+		__u8	s_jnl_backup_type;
+		__le16  s_desc_size;		/* size of group descriptor */
+	/*100*/	__le32	s_default_mount_opts;
+		__le32	s_first_meta_bg;	/* First metablock block group */
+		__le32	s_mkfs_time;		/* When the filesystem was created */
+		__le32	s_jnl_blocks[17];	/* Backup of the journal inode */
+	/*150*/	__le32	s_blocks_count_hi;	/* Blocks count */
+		__le32	s_r_blocks_count_hi;	/* Reserved blocks count */
+		__le32	s_free_blocks_count_hi;	/* Free blocks count */
+		__le16	s_min_extra_isize;	/* All inodes have at least # bytes */
+		__le16	s_want_extra_isize; 	/* New inodes should reserve # bytes */
+		__le32	s_flags;		/* Miscellaneous flags */
+		__le16  s_raid_stride;		/* RAID stride */
+		__le16  s_mmp_update_interval;  /* # seconds to wait in MMP checking */
+		__le64  s_mmp_block;            /* Block for multi-mount protection */
+		__le32  s_raid_stripe_width;    /* blocks on all data disks (N*stride)*/
+		__u8	s_log_groups_per_flex;  /* FLEX_BG group size */
+		__u8	s_checksum_type;	/* metadata checksum algorithm used */
+		__u8	s_encryption_level;	/* versioning level for encryption */
+		__u8	s_reserved_pad;		/* Padding to next 32bits */
+		__le64	s_kbytes_written;	/* nr of lifetime kilobytes written */
+		__le32	s_snapshot_inum;	/* Inode number of active snapshot */
+		__le32	s_snapshot_id;		/* sequential ID of active snapshot */
+		__le64	s_snapshot_r_blocks_count; /* reserved blocks for active
+						      snapshot's future use */
+		__le32	s_snapshot_list;	/* inode number of the head of the
+						   on-disk snapshot list */
+		__le32	s_error_count;		/* number of fs errors */
+		__le32	s_first_error_time;	/* first time an error happened */
+		__le32	s_first_error_ino;	/* inode involved in first error */
+		__le64	s_first_error_block;	/* block involved of first error */
+		__u8	s_first_error_func[32];	/* function where the error happened */
+		__le32	s_first_error_line;	/* line number where error happened */
+		__le32	s_last_error_time;	/* most recent time of an error */
+		__le32	s_last_error_ino;	/* inode involved in last error */
+		__le32	s_last_error_line;	/* line number where error happened */
+		__le64	s_last_error_block;	/* block involved of last error */
+		__u8	s_last_error_func[32];	/* function where the error happened */
+		__u8	s_mount_opts[64];
+		__le32	s_usr_quota_inum;	/* inode for tracking user quota */
+		__le32	s_grp_quota_inum;	/* inode for tracking group quota */
+		__le32	s_overhead_clusters;	/* overhead blocks/clusters in fs */
+		__le32	s_backup_bgs[2];	/* groups with sparse_super2 SBs */
+		__u8	s_encrypt_algos[4];	/* Encryption algorithms in use  */
+		__u8	s_encrypt_pw_salt[16];	/* Salt used for string2key algorithm */
+		__le32	s_lpf_ino;		/* Location of the lost+found inode */
+		__le32	s_prj_quota_inum;	/* inode for tracking project quota */
+		__le32	s_checksum_seed;	/* crc32c(uuid) if csum_seed set */
+		__u8	s_wtime_hi;
+		__u8	s_mtime_hi;
+		__u8	s_mkfs_time_hi;
+		__u8	s_lastcheck_hi;
+		__u8	s_first_error_time_hi;
+		__u8	s_last_error_time_hi;
+		__u8	s_first_error_errcode;
+		__u8    s_last_error_errcode;
+		__le16  s_encoding;		/* Filename charset encoding */
+		__le16  s_encoding_flags;	/* Filename charset encoding flags */
+		__le32	s_reserved[95];		/* Padding to the end of the block */
+		__le32	s_checksum;		/* crc32c(superblock) */
+	} *r = reply;
+	char buffer[100];
+
+#define Z(S) ((unsigned long long)__le32_to_cpu(S) | (((unsigned long long)S##_hi) << 32))
+
+	printf("\n");
+	printf("\tmkfs    : %s\n", dump_ext4_time(buffer, Z(r->s_mkfs_time)));
+	printf("\tmount   : %s\n", dump_ext4_time(buffer, Z(r->s_mtime)));
+	printf("\twrite   : %s\n", dump_ext4_time(buffer, Z(r->s_wtime)));
+	printf("\tfsck    : %s\n", dump_ext4_time(buffer, Z(r->s_lastcheck)));
+	printf("\t1st-err : %s\n", dump_ext4_time(buffer, Z(r->s_first_error_time)));
+	printf("\tlast-err: %s\n", dump_ext4_time(buffer, Z(r->s_last_error_time)));
+}
+
 static void dump_string(void *reply, unsigned int size)
 {
 	char *s = reply, *p;
@@ -476,6 +618,7 @@ static const struct fsinfo_attribute fsinfo_attributes[] = {
 	FSINFO_STRING	(FSINFO_ATTR_AFS_CELL_NAME,	string),
 	FSINFO_STRING	(FSINFO_ATTR_AFS_SERVER_NAME,	string),
 	FSINFO_LIST_N	(FSINFO_ATTR_AFS_SERVER_ADDRESSES, afs_fsinfo_server_address),
+	FSINFO_OPAQUE	(FSINFO_ATTR_EXT4_SUPERBLOCK,	ext4_fsinfo_superblock),
 	{}
 };
 

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Exporting ext4-specific information through fsinfo attributes
  2020-04-21 16:17 ` David Howells
@ 2020-04-21 22:07   ` Andreas Dilger
  2020-04-22 16:12     ` Darrick J. Wong
  2020-07-21  9:20     ` David Howells
  2020-04-22 14:27   ` David Howells
                     ` (2 subsequent siblings)
  3 siblings, 2 replies; 15+ messages in thread
From: Andreas Dilger @ 2020-04-21 22:07 UTC (permalink / raw)
  To: David Howells
  Cc: Darrick J. Wong, Eric Biggers, Theodore Ts'o, Ext4 Developers List


[-- Attachment #1: Type: text/plain, Size: 1629 bytes --]

On Apr 21, 2020, at 10:17 AM, David Howells <dhowells@redhat.com> wrote:
> 
> Darrick J. Wong <darrick.wong@oracle.com> wrote:
> 
>> The entire superblock as a binary blob? :)
> 
> How about the attached?  Please forgive the duplication of struct
> ext4_super_block into the test program, but it's not in the UAPI.

I think (hope?) Darrick was joking?

At least IMHO, exporting the whole superblock as a binary blob is not
a great user interface.  I guess it has the benefit of allowing access
to various non-standard fields without accessing the device directly.
Kind of like SCSI mode pages, but that can get ugly quickly...

I can definitely get behind adding generic properties like the ones
you list below.

> 
> David
> ---
> fsinfo: Add support to ext4
> 
> Add support to ext4, including the following:
> 
> (1) FSINFO_ATTR_SUPPORTS: Information about supported STATX attributes and
>     support for ioctls like FS_IOC_[GS]ETFLAGS and FS_IOC_FS[GS]ETXATTR.
> 
> (2) FSINFO_ATTR_FEATURES: Information about features supported by an ext4
>     filesystem, such as whether version counting, birth time and name case
>     folding are in operation.
> 
> (3) FSINFO_ATTR_VOLUME_NAME: The volume name from the superblock.
> 
> (4) FSINFO_ATTR_EXT4_SUPERBLOCK: The entirety of the on disk-format
>     superblock record as an opaque blob.
> 
> Signed-off-by: David Howells <dhowells@redhat.com>
> cc: "Theodore Ts'o" <tytso@mit.edu>
> cc: Andreas Dilger <adilger.kernel@dilger.ca>
> cc: "Darrick J. Wong" <darrick.wong@oracle.com>
> cc: Eric Biggers <ebiggers@kernel.org>
> cc: linux-ext4@vger.kernel.org

Cheers, Andreas






[-- Attachment #2: Message signed with OpenPGP --]
[-- Type: application/pgp-signature, Size: 873 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Exporting ext4-specific information through fsinfo attributes
  2020-04-21 16:17 ` David Howells
  2020-04-21 22:07   ` Andreas Dilger
@ 2020-04-22 14:27   ` David Howells
  2020-07-21 15:42   ` Darrick J. Wong
  2020-07-22  8:53   ` David Howells
  3 siblings, 0 replies; 15+ messages in thread
From: David Howells @ 2020-04-22 14:27 UTC (permalink / raw)
  To: Andreas Dilger
  Cc: dhowells, Darrick J. Wong, Eric Biggers, Theodore Ts'o,
	Ext4 Developers List

Andreas Dilger <adilger@dilger.ca> wrote:

> I can definitely get behind adding generic properties like the ones
> you list below.

Are there any specific properties you'd like exported through this interface?

David


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Exporting ext4-specific information through fsinfo attributes
  2020-04-21 22:07   ` Andreas Dilger
@ 2020-04-22 16:12     ` Darrick J. Wong
  2020-07-21  9:20     ` David Howells
  1 sibling, 0 replies; 15+ messages in thread
From: Darrick J. Wong @ 2020-04-22 16:12 UTC (permalink / raw)
  To: Andreas Dilger
  Cc: David Howells, Eric Biggers, Theodore Ts'o, Ext4 Developers List

On Tue, Apr 21, 2020 at 04:07:43PM -0600, Andreas Dilger wrote:
> On Apr 21, 2020, at 10:17 AM, David Howells <dhowells@redhat.com> wrote:
> > 
> > Darrick J. Wong <darrick.wong@oracle.com> wrote:
> > 
> >> The entire superblock as a binary blob? :)
> > 
> > How about the attached?  Please forgive the duplication of struct
> > ext4_super_block into the test program, but it's not in the UAPI.
> 
> I think (hope?) Darrick was joking?

<cough> 80% joking.  It /was/ April 1st, after all. :)

Ted has said on a few occasions that one of the big stumbling blocks to
making tune2fs safe wrt mounted ext4 is that there's no way to get or
set superblock fields in a way that's kernel-mediated, and maybe the
easiest way is to export the superblock instead of playing this game
with synchronous sb writes from the kernel and the strange
mask-and-write behavior that tune2fs does.

I'm not convinced that's the best way to do that, though at least for
/reading/ the superblock I guess it beats defining a whole new structure
and ioctl.

> At least IMHO, exporting the whole superblock as a binary blob is not
> a great user interface.  I guess it has the benefit of allowing access
> to various non-standard fields without accessing the device directly.
> Kind of like SCSI mode pages, but that can get ugly quickly...
> 
> I can definitely get behind adding generic properties like the ones
> you list below.

The other properties look fine (in principle) to me though. :)

--D

> > 
> > David
> > ---
> > fsinfo: Add support to ext4
> > 
> > Add support to ext4, including the following:
> > 
> > (1) FSINFO_ATTR_SUPPORTS: Information about supported STATX attributes and
> >     support for ioctls like FS_IOC_[GS]ETFLAGS and FS_IOC_FS[GS]ETXATTR.
> > 
> > (2) FSINFO_ATTR_FEATURES: Information about features supported by an ext4
> >     filesystem, such as whether version counting, birth time and name case
> >     folding are in operation.
> > 
> > (3) FSINFO_ATTR_VOLUME_NAME: The volume name from the superblock.
> > 
> > (4) FSINFO_ATTR_EXT4_SUPERBLOCK: The entirety of the on disk-format
> >     superblock record as an opaque blob.
> > 
> > Signed-off-by: David Howells <dhowells@redhat.com>
> > cc: "Theodore Ts'o" <tytso@mit.edu>
> > cc: Andreas Dilger <adilger.kernel@dilger.ca>
> > cc: "Darrick J. Wong" <darrick.wong@oracle.com>
> > cc: Eric Biggers <ebiggers@kernel.org>
> > cc: linux-ext4@vger.kernel.org
> 
> Cheers, Andreas
> 
> 
> 
> 
> 



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Exporting ext4-specific information through fsinfo attributes
  2020-04-21 22:07   ` Andreas Dilger
  2020-04-22 16:12     ` Darrick J. Wong
@ 2020-07-21  9:20     ` David Howells
  2020-07-21 15:37       ` Darrick J. Wong
  1 sibling, 1 reply; 15+ messages in thread
From: David Howells @ 2020-07-21  9:20 UTC (permalink / raw)
  To: Darrick J. Wong
  Cc: dhowells, Andreas Dilger, Eric Biggers, Theodore Ts'o,
	Ext4 Developers List

Darrick J. Wong <darrick.wong@oracle.com> wrote:

> The other properties look fine (in principle) to me though. :)

Can I put that down as a reviewed-by?

Thanks,
David


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Exporting ext4-specific information through fsinfo attributes
  2020-07-21  9:20     ` David Howells
@ 2020-07-21 15:37       ` Darrick J. Wong
  0 siblings, 0 replies; 15+ messages in thread
From: Darrick J. Wong @ 2020-07-21 15:37 UTC (permalink / raw)
  To: David Howells
  Cc: Andreas Dilger, Eric Biggers, Theodore Ts'o, Ext4 Developers List

On Tue, Jul 21, 2020 at 10:20:35AM +0100, David Howells wrote:
> Darrick J. Wong <darrick.wong@oracle.com> wrote:
> 
> > The other properties look fine (in principle) to me though. :)
> 
> Can I put that down as a reviewed-by?

Hang on, let me take a second look and do a real review. :)

--D

> Thanks,
> David
> 

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Exporting ext4-specific information through fsinfo attributes
  2020-04-21 16:17 ` David Howells
  2020-04-21 22:07   ` Andreas Dilger
  2020-04-22 14:27   ` David Howells
@ 2020-07-21 15:42   ` Darrick J. Wong
  2020-07-22  8:53   ` David Howells
  3 siblings, 0 replies; 15+ messages in thread
From: Darrick J. Wong @ 2020-07-21 15:42 UTC (permalink / raw)
  To: David Howells; +Cc: Eric Biggers, tytso, adilger.kernel, linux-ext4

On Tue, Apr 21, 2020 at 05:17:22PM +0100, David Howells wrote:
> Darrick J. Wong <darrick.wong@oracle.com> wrote:
> 
> > The entire superblock as a binary blob? :)
> 
> How about the attached?  Please forgive the duplication of struct
> ext4_super_block into the test program, but it's not in the UAPI.
> 
> David
> ---
> fsinfo: Add support to ext4
>     
> Add support to ext4, including the following:
> 
>  (1) FSINFO_ATTR_SUPPORTS: Information about supported STATX attributes and
>      support for ioctls like FS_IOC_[GS]ETFLAGS and FS_IOC_FS[GS]ETXATTR.
> 
>  (2) FSINFO_ATTR_FEATURES: Information about features supported by an ext4
>      filesystem, such as whether version counting, birth time and name case
>      folding are in operation.
> 
>  (3) FSINFO_ATTR_VOLUME_NAME: The volume name from the superblock.
> 
>  (4) FSINFO_ATTR_EXT4_SUPERBLOCK: The entirety of the on disk-format
>      superblock record as an opaque blob.
> 
> Signed-off-by: David Howells <dhowells@redhat.com>
> cc: "Theodore Ts'o" <tytso@mit.edu>
> cc: Andreas Dilger <adilger.kernel@dilger.ca>
> cc: "Darrick J. Wong" <darrick.wong@oracle.com>
> cc: Eric Biggers <ebiggers@kernel.org>
> cc: linux-ext4@vger.kernel.org
> ---
>  fs/ext4/Makefile            |    1 
>  fs/ext4/ext4.h              |    6 +
>  fs/ext4/fsinfo.c            |  106 ++++++++++++++++++++++++++++++++
>  fs/ext4/super.c             |    3 
>  include/uapi/linux/fsinfo.h |    2 
>  samples/vfs/test-fsinfo.c   |  143 ++++++++++++++++++++++++++++++++++++++++++++
>  6 files changed, 261 insertions(+)
> 
> 
> diff --git a/fs/ext4/Makefile b/fs/ext4/Makefile
> index 4ccb3c9189d8..71d5b460c7c7 100644
> --- a/fs/ext4/Makefile
> +++ b/fs/ext4/Makefile
> @@ -16,3 +16,4 @@ ext4-$(CONFIG_EXT4_FS_SECURITY)		+= xattr_security.o
>  ext4-inode-test-objs			+= inode-test.o
>  obj-$(CONFIG_EXT4_KUNIT_TESTS)		+= ext4-inode-test.o
>  ext4-$(CONFIG_FS_VERITY)		+= verity.o
> +ext4-$(CONFIG_FSINFO)			+= fsinfo.o
> diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
> index 91eb4381cae5..674581da786c 100644
> --- a/fs/ext4/ext4.h
> +++ b/fs/ext4/ext4.h
> @@ -42,6 +42,7 @@
>  
>  #include <linux/fscrypt.h>
>  #include <linux/fsverity.h>
> +#include <linux/fsinfo.h>
>  
>  #include <linux/compiler.h>
>  
> @@ -3207,6 +3208,11 @@ extern const struct inode_operations ext4_file_inode_operations;
>  extern const struct file_operations ext4_file_operations;
>  extern loff_t ext4_llseek(struct file *file, loff_t offset, int origin);
>  
> +/* fsinfo.c */
> +#ifdef CONFIG_FSINFO
> +extern int ext4_fsinfo(struct path *path, struct fsinfo_context *ctx);
> +#endif
> +
>  /* inline.c */
>  extern int ext4_get_max_inline_size(struct inode *inode);
>  extern int ext4_find_inline_data_nolock(struct inode *inode);
> diff --git a/fs/ext4/fsinfo.c b/fs/ext4/fsinfo.c
> new file mode 100644
> index 000000000000..52bfd09e550f
> --- /dev/null
> +++ b/fs/ext4/fsinfo.c
> @@ -0,0 +1,106 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/* Filesystem information for ext4
> + *
> + * Copyright (C) 2020 Red Hat, Inc. All Rights Reserved.
> + * Written by David Howells (dhowells@redhat.com)
> + */
> +
> +#include <linux/mount.h>
> +#include "ext4.h"
> +
> +static int ext4_fsinfo_supports(struct path *path, struct fsinfo_context *ctx)
> +{
> +	struct fsinfo_supports *p = ctx->buffer;
> +	struct inode *inode = d_inode(path->dentry);
> +	struct ext4_inode_info *ei = EXT4_I(inode);
> +	struct ext4_inode *raw_inode;
> +	u32 flags;
> +
> +	fsinfo_generic_supports(path, ctx);
> +	p->stx_attributes |= (STATX_ATTR_APPEND |
> +			      STATX_ATTR_COMPRESSED |
> +			      STATX_ATTR_ENCRYPTED |
> +			      STATX_ATTR_IMMUTABLE |
> +			      STATX_ATTR_NODUMP |
> +			      STATX_ATTR_VERITY);
> +	if (EXT4_FITS_IN_INODE(raw_inode, ei, i_crtime))
> +		p->stx_mask |= STATX_BTIME;
> +
> +	flags = EXT4_FL_USER_VISIBLE;
> +	if (S_ISREG(inode->i_mode))
> +		flags &= ~EXT4_PROJINHERIT_FL;
> +	p->fs_ioc_getflags = flags;
> +	flags &= EXT4_FL_USER_MODIFIABLE;
> +	p->fs_ioc_setflags_set = flags;
> +	p->fs_ioc_setflags_clear = flags;
> +
> +	p->fs_ioc_fsgetxattr_xflags = EXT4_FL_XFLAG_VISIBLE;
> +	p->fs_ioc_fssetxattr_xflags_set = EXT4_FL_XFLAG_VISIBLE;
> +	p->fs_ioc_fssetxattr_xflags_clear = EXT4_FL_XFLAG_VISIBLE;

Oooh.... I like that we finally have a way to tell userspace which bits
actually have any meaning. :)

> +	return sizeof(*p);
> +}
> +
> +static int ext4_fsinfo_features(struct path *path, struct fsinfo_context *ctx)
> +{
> +	struct fsinfo_features *p = ctx->buffer;
> +	struct super_block *sb = path->dentry->d_sb;
> +	struct inode *inode = d_inode(path->dentry);
> +	struct ext4_inode_info *ei = EXT4_I(inode);
> +	struct ext4_inode *raw_inode;
> +
> +	fsinfo_generic_features(path, ctx);
> +	fsinfo_set_unix_features(p);
> +	fsinfo_set_feature(p, FSINFO_FEAT_VOLUME_UUID);
> +	fsinfo_set_feature(p, FSINFO_FEAT_VOLUME_NAME);
> +	fsinfo_set_feature(p, FSINFO_FEAT_O_SYNC);
> +	fsinfo_set_feature(p, FSINFO_FEAT_O_DIRECT);
> +	fsinfo_set_feature(p, FSINFO_FEAT_ADV_LOCKS);

Where are these FSINFO_FEAT* constants defined, and where are they
documented?

This generally looks ok to me, but I would like to see documentation
first.

--D

> +
> +	if (test_opt(sb, XATTR_USER))
> +		fsinfo_set_feature(p, FSINFO_FEAT_XATTRS);
> +	if (ext4_has_feature_journal(sb))
> +		fsinfo_set_feature(p, FSINFO_FEAT_JOURNAL);
> +	if (ext4_has_feature_casefold(sb))
> +		fsinfo_set_feature(p, FSINFO_FEAT_NAME_CASE_INDEP);
> +
> +	if (sb->s_flags & SB_I_VERSION &&
> +	    !test_opt2(sb, HURD_COMPAT) &&
> +	    EXT4_INODE_SIZE(sb) > EXT4_GOOD_OLD_INODE_SIZE) {
> +		fsinfo_set_feature(p, FSINFO_FEAT_IVER_DATA_CHANGE);
> +		fsinfo_set_feature(p, FSINFO_FEAT_IVER_MONO_INCR);
> +	}
> +
> +	if (EXT4_FITS_IN_INODE(raw_inode, ei, i_crtime))
> +		fsinfo_set_feature(p, FSINFO_FEAT_HAS_BTIME);
> +	return sizeof(*p);
> +}
> +
> +static int ext4_fsinfo_get_volume_name(struct path *path, struct fsinfo_context *ctx)
> +{
> +	const struct ext4_sb_info *sbi = EXT4_SB(path->mnt->mnt_sb);
> +	const struct ext4_super_block *es = sbi->s_es;
> +
> +	memcpy(ctx->buffer, es->s_volume_name, sizeof(es->s_volume_name));
> +	return strlen(ctx->buffer) + 1;
> +}
> +
> +static int ext4_fsinfo_get_superblock(struct path *path, struct fsinfo_context *ctx)
> +{
> +	const struct ext4_sb_info *sbi = EXT4_SB(path->mnt->mnt_sb);
> +	const struct ext4_super_block *es = sbi->s_es;
> +
> +	return fsinfo_opaque(es, ctx, sizeof(*es));
> +}
> +
> +static const struct fsinfo_attribute ext4_fsinfo_attributes[] = {
> +	FSINFO_VSTRUCT	(FSINFO_ATTR_SUPPORTS,		ext4_fsinfo_supports),
> +	FSINFO_VSTRUCT	(FSINFO_ATTR_FEATURES,		ext4_fsinfo_features),
> +	FSINFO_STRING	(FSINFO_ATTR_VOLUME_NAME,	ext4_fsinfo_get_volume_name),
> +	FSINFO_OPAQUE	(FSINFO_ATTR_EXT4_SUPERBLOCK,	ext4_fsinfo_get_superblock),
> +	{}
> +};
> +
> +int ext4_fsinfo(struct path *path, struct fsinfo_context *ctx)
> +{
> +	return fsinfo_get_attribute(path, ctx, ext4_fsinfo_attributes);
> +}
> diff --git a/fs/ext4/super.c b/fs/ext4/super.c
> index bf5fcb477f66..201287a90c4b 100644
> --- a/fs/ext4/super.c
> +++ b/fs/ext4/super.c
> @@ -1482,6 +1482,9 @@ static const struct super_operations ext4_sops = {
>  	.freeze_fs	= ext4_freeze,
>  	.unfreeze_fs	= ext4_unfreeze,
>  	.statfs		= ext4_statfs,
> +#ifdef CONFIG_FSINFO
> +	.fsinfo		= ext4_fsinfo,
> +#endif
>  	.remount_fs	= ext4_remount,
>  	.show_options	= ext4_show_options,
>  #ifdef CONFIG_QUOTA
> diff --git a/include/uapi/linux/fsinfo.h b/include/uapi/linux/fsinfo.h
> index 3483dd9a5d05..51214c0c82b1 100644
> --- a/include/uapi/linux/fsinfo.h
> +++ b/include/uapi/linux/fsinfo.h
> @@ -42,6 +42,8 @@
>  #define FSINFO_ATTR_AFS_SERVER_NAME	0x301	/* Name of the Nth server (string) */
>  #define FSINFO_ATTR_AFS_SERVER_ADDRESSES 0x302	/* List of addresses of the Nth server */
>  
> +#define FSINFO_ATTR_EXT4_SUPERBLOCK	0x400	/* Ext4 superblock (opaque) */
> +
>  /*
>   * Optional fsinfo() parameter structure.
>   *
> diff --git a/samples/vfs/test-fsinfo.c b/samples/vfs/test-fsinfo.c
> index 4c6f3f1002dd..a6dacc2ec59d 100644
> --- a/samples/vfs/test-fsinfo.c
> +++ b/samples/vfs/test-fsinfo.c
> @@ -24,6 +24,7 @@
>  #include <sys/stat.h>
>  #include <arpa/inet.h>
>  #include <linux/rxrpc.h>
> +#include <linux/byteorder/little_endian.h>
>  
>  #ifndef __NR_fsinfo
>  #define __NR_fsinfo -1
> @@ -389,6 +390,147 @@ static void dump_afs_fsinfo_server_address(void *reply, unsigned int size)
>  	printf("family=%u\n", ss->ss_family);
>  }
>  
> +static char *dump_ext4_time(char *buffer, time_t tim)
> +{
> +	struct tm tm;
> +	int len;
> +
> +	if (tim == 0)
> +		return "-";
> +
> +	if (!localtime_r(&tim, &tm)) {
> +		perror("localtime_r");
> +		exit(1);
> +	}
> +	len = strftime(buffer, 100, "%F %T", &tm);
> +	if (len == 0) {
> +		perror("strftime");
> +		exit(1);
> +	}
> +	return buffer;
> +}
> +
> +static void dump_ext4_fsinfo_superblock(void *reply, unsigned int size)
> +{
> +	struct ext4_super_block {
> +	/*00*/	__le32	s_inodes_count;		/* Inodes count */
> +		__le32	s_blocks_count_lo;	/* Blocks count */
> +		__le32	s_r_blocks_count_lo;	/* Reserved blocks count */
> +		__le32	s_free_blocks_count_lo;	/* Free blocks count */
> +	/*10*/	__le32	s_free_inodes_count;	/* Free inodes count */
> +		__le32	s_first_data_block;	/* First Data Block */
> +		__le32	s_log_block_size;	/* Block size */
> +		__le32	s_log_cluster_size;	/* Allocation cluster size */
> +	/*20*/	__le32	s_blocks_per_group;	/* # Blocks per group */
> +		__le32	s_clusters_per_group;	/* # Clusters per group */
> +		__le32	s_inodes_per_group;	/* # Inodes per group */
> +		__le32	s_mtime;		/* Mount time */
> +	/*30*/	__le32	s_wtime;		/* Write time */
> +		__le16	s_mnt_count;		/* Mount count */
> +		__le16	s_max_mnt_count;	/* Maximal mount count */
> +		__le16	s_magic;		/* Magic signature */
> +		__le16	s_state;		/* File system state */
> +		__le16	s_errors;		/* Behaviour when detecting errors */
> +		__le16	s_minor_rev_level;	/* minor revision level */
> +	/*40*/	__le32	s_lastcheck;		/* time of last check */
> +		__le32	s_checkinterval;	/* max. time between checks */
> +		__le32	s_creator_os;		/* OS */
> +		__le32	s_rev_level;		/* Revision level */
> +	/*50*/	__le16	s_def_resuid;		/* Default uid for reserved blocks */
> +		__le16	s_def_resgid;		/* Default gid for reserved blocks */
> +		__le32	s_first_ino;		/* First non-reserved inode */
> +		__le16  s_inode_size;		/* size of inode structure */
> +		__le16	s_block_group_nr;	/* block group # of this superblock */
> +		__le32	s_feature_compat;	/* compatible feature set */
> +	/*60*/	__le32	s_feature_incompat;	/* incompatible feature set */
> +		__le32	s_feature_ro_compat;	/* readonly-compatible feature set */
> +	/*68*/	__u8	s_uuid[16];		/* 128-bit uuid for volume */
> +	/*78*/	char	s_volume_name[16];	/* volume name */
> +	/*88*/	char	s_last_mounted[64];	/* directory where last mounted */
> +	/*C8*/	__le32	s_algorithm_usage_bitmap; /* For compression */
> +		__u8	s_prealloc_blocks;	/* Nr of blocks to try to preallocate*/
> +		__u8	s_prealloc_dir_blocks;	/* Nr to preallocate for dirs */
> +		__le16	s_reserved_gdt_blocks;	/* Per group desc for online growth */
> +	/*D0*/	__u8	s_journal_uuid[16];	/* uuid of journal superblock */
> +	/*E0*/	__le32	s_journal_inum;		/* inode number of journal file */
> +		__le32	s_journal_dev;		/* device number of journal file */
> +		__le32	s_last_orphan;		/* start of list of inodes to delete */
> +		__le32	s_hash_seed[4];		/* HTREE hash seed */
> +		__u8	s_def_hash_version;	/* Default hash version to use */
> +		__u8	s_jnl_backup_type;
> +		__le16  s_desc_size;		/* size of group descriptor */
> +	/*100*/	__le32	s_default_mount_opts;
> +		__le32	s_first_meta_bg;	/* First metablock block group */
> +		__le32	s_mkfs_time;		/* When the filesystem was created */
> +		__le32	s_jnl_blocks[17];	/* Backup of the journal inode */
> +	/*150*/	__le32	s_blocks_count_hi;	/* Blocks count */
> +		__le32	s_r_blocks_count_hi;	/* Reserved blocks count */
> +		__le32	s_free_blocks_count_hi;	/* Free blocks count */
> +		__le16	s_min_extra_isize;	/* All inodes have at least # bytes */
> +		__le16	s_want_extra_isize; 	/* New inodes should reserve # bytes */
> +		__le32	s_flags;		/* Miscellaneous flags */
> +		__le16  s_raid_stride;		/* RAID stride */
> +		__le16  s_mmp_update_interval;  /* # seconds to wait in MMP checking */
> +		__le64  s_mmp_block;            /* Block for multi-mount protection */
> +		__le32  s_raid_stripe_width;    /* blocks on all data disks (N*stride)*/
> +		__u8	s_log_groups_per_flex;  /* FLEX_BG group size */
> +		__u8	s_checksum_type;	/* metadata checksum algorithm used */
> +		__u8	s_encryption_level;	/* versioning level for encryption */
> +		__u8	s_reserved_pad;		/* Padding to next 32bits */
> +		__le64	s_kbytes_written;	/* nr of lifetime kilobytes written */
> +		__le32	s_snapshot_inum;	/* Inode number of active snapshot */
> +		__le32	s_snapshot_id;		/* sequential ID of active snapshot */
> +		__le64	s_snapshot_r_blocks_count; /* reserved blocks for active
> +						      snapshot's future use */
> +		__le32	s_snapshot_list;	/* inode number of the head of the
> +						   on-disk snapshot list */
> +		__le32	s_error_count;		/* number of fs errors */
> +		__le32	s_first_error_time;	/* first time an error happened */
> +		__le32	s_first_error_ino;	/* inode involved in first error */
> +		__le64	s_first_error_block;	/* block involved of first error */
> +		__u8	s_first_error_func[32];	/* function where the error happened */
> +		__le32	s_first_error_line;	/* line number where error happened */
> +		__le32	s_last_error_time;	/* most recent time of an error */
> +		__le32	s_last_error_ino;	/* inode involved in last error */
> +		__le32	s_last_error_line;	/* line number where error happened */
> +		__le64	s_last_error_block;	/* block involved of last error */
> +		__u8	s_last_error_func[32];	/* function where the error happened */
> +		__u8	s_mount_opts[64];
> +		__le32	s_usr_quota_inum;	/* inode for tracking user quota */
> +		__le32	s_grp_quota_inum;	/* inode for tracking group quota */
> +		__le32	s_overhead_clusters;	/* overhead blocks/clusters in fs */
> +		__le32	s_backup_bgs[2];	/* groups with sparse_super2 SBs */
> +		__u8	s_encrypt_algos[4];	/* Encryption algorithms in use  */
> +		__u8	s_encrypt_pw_salt[16];	/* Salt used for string2key algorithm */
> +		__le32	s_lpf_ino;		/* Location of the lost+found inode */
> +		__le32	s_prj_quota_inum;	/* inode for tracking project quota */
> +		__le32	s_checksum_seed;	/* crc32c(uuid) if csum_seed set */
> +		__u8	s_wtime_hi;
> +		__u8	s_mtime_hi;
> +		__u8	s_mkfs_time_hi;
> +		__u8	s_lastcheck_hi;
> +		__u8	s_first_error_time_hi;
> +		__u8	s_last_error_time_hi;
> +		__u8	s_first_error_errcode;
> +		__u8    s_last_error_errcode;
> +		__le16  s_encoding;		/* Filename charset encoding */
> +		__le16  s_encoding_flags;	/* Filename charset encoding flags */
> +		__le32	s_reserved[95];		/* Padding to the end of the block */
> +		__le32	s_checksum;		/* crc32c(superblock) */
> +	} *r = reply;
> +	char buffer[100];
> +
> +#define Z(S) ((unsigned long long)__le32_to_cpu(S) | (((unsigned long long)S##_hi) << 32))
> +
> +	printf("\n");
> +	printf("\tmkfs    : %s\n", dump_ext4_time(buffer, Z(r->s_mkfs_time)));
> +	printf("\tmount   : %s\n", dump_ext4_time(buffer, Z(r->s_mtime)));
> +	printf("\twrite   : %s\n", dump_ext4_time(buffer, Z(r->s_wtime)));
> +	printf("\tfsck    : %s\n", dump_ext4_time(buffer, Z(r->s_lastcheck)));
> +	printf("\t1st-err : %s\n", dump_ext4_time(buffer, Z(r->s_first_error_time)));
> +	printf("\tlast-err: %s\n", dump_ext4_time(buffer, Z(r->s_last_error_time)));
> +}
> +
>  static void dump_string(void *reply, unsigned int size)
>  {
>  	char *s = reply, *p;
> @@ -476,6 +618,7 @@ static const struct fsinfo_attribute fsinfo_attributes[] = {
>  	FSINFO_STRING	(FSINFO_ATTR_AFS_CELL_NAME,	string),
>  	FSINFO_STRING	(FSINFO_ATTR_AFS_SERVER_NAME,	string),
>  	FSINFO_LIST_N	(FSINFO_ATTR_AFS_SERVER_ADDRESSES, afs_fsinfo_server_address),
> +	FSINFO_OPAQUE	(FSINFO_ATTR_EXT4_SUPERBLOCK,	ext4_fsinfo_superblock),
>  	{}
>  };
>  

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Exporting ext4-specific information through fsinfo attributes
  2020-04-21 16:17 ` David Howells
                     ` (2 preceding siblings ...)
  2020-07-21 15:42   ` Darrick J. Wong
@ 2020-07-22  8:53   ` David Howells
  2020-07-22 15:25     ` Darrick J. Wong
  3 siblings, 1 reply; 15+ messages in thread
From: David Howells @ 2020-07-22  8:53 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: dhowells, Eric Biggers, tytso, adilger.kernel, linux-ext4

Darrick J. Wong <darrick.wong@oracle.com> wrote:

> Where are these FSINFO_FEAT* constants defined, and where are they
> documented?
> 
> This generally looks ok to me, but I would like to see documentation
> first.

Have a look at this branch:

	https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/log/?h=fsinfo-core

Patch "fsinfo: Provide a bitmap of supported features"

	https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit/?h=fsinfo-core&id=9d7651e966331f18c7bfe053237b3627585c3e79

Documentation:

	https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit/?h=fsinfo-core&id=6bb357c42c96c2a5d72ff02d109ce49bd0c455ab

David


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Exporting ext4-specific information through fsinfo attributes
  2020-07-22  8:53   ` David Howells
@ 2020-07-22 15:25     ` Darrick J. Wong
  0 siblings, 0 replies; 15+ messages in thread
From: Darrick J. Wong @ 2020-07-22 15:25 UTC (permalink / raw)
  To: David Howells; +Cc: Eric Biggers, tytso, adilger.kernel, linux-ext4

On Wed, Jul 22, 2020 at 09:53:06AM +0100, David Howells wrote:
> Darrick J. Wong <darrick.wong@oracle.com> wrote:
> 
> > Where are these FSINFO_FEAT* constants defined, and where are they
> > documented?
> > 
> > This generally looks ok to me, but I would like to see documentation
> > first.
> 
> Have a look at this branch:
> 
> 	https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/log/?h=fsinfo-core
> 
> Patch "fsinfo: Provide a bitmap of supported features"
> 
> 	https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit/?h=fsinfo-core&id=9d7651e966331f18c7bfe053237b3627585c3e79
> 
> Documentation:
> 
> 	https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit/?h=fsinfo-core&id=6bb357c42c96c2a5d72ff02d109ce49bd0c455ab

Ah, thank you.  The ext4 bits look ok to me.

Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>

(Looking forward to whenever you get to xfs... :))

--D


> David
> 

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, back to index

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-01  7:39 Exporting ext4-specific information through fsinfo attributes David Howells
2020-04-01 15:18 ` Darrick J. Wong
2020-04-01 16:27 ` Eric Biggers
2020-04-01 19:05   ` Darrick J. Wong
2020-04-01 19:28     ` Eric Biggers
2020-04-01 20:36       ` Eric Biggers
2020-04-21 16:17 ` David Howells
2020-04-21 22:07   ` Andreas Dilger
2020-04-22 16:12     ` Darrick J. Wong
2020-07-21  9:20     ` David Howells
2020-07-21 15:37       ` Darrick J. Wong
2020-04-22 14:27   ` David Howells
2020-07-21 15:42   ` Darrick J. Wong
2020-07-22  8:53   ` David Howells
2020-07-22 15:25     ` Darrick J. Wong

Linux-ext4 Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-ext4/0 linux-ext4/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-ext4 linux-ext4/ https://lore.kernel.org/linux-ext4 \
		linux-ext4@vger.kernel.org
	public-inbox-index linux-ext4

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-ext4


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git