On Tue, Feb 09, 2021 at 02:03:19PM -0800, Linus Torvalds wrote: > On Tue, Feb 9, 2021 at 1:42 PM Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> wrote: > > > > As with s390, alpha is a 64-bit architecture with a 32-bit ino_t. With > > CONFIG_TMPFS_INODE64=y tmpfs mounts will get 64-bit inode numbers and > > display "inode64" in the mount options, whereas passing "inode64" in the > > mount options will fail. > > Ugh. > > The two patches for s390 and alpha are obviously the right thing to > do, but I do wonder if we could strive to make __kernel_ino_t go away > entirely. > > It's actually not used very much, because it's such a nasty type, and > s390 and alpha are the only ones that override it from the default > "word length" version (and honestly, even that default is not a great > type). > > The main use of it is for "ino_t" and for "struct ustat". > > And yes, "ino_t" is widely used, but I think pretty much all uses of > it are entirely internal to the kernel, and we could just make it be > "unsigned long". > > Does anybody see any actual user interfaces that depend on > "__kernel_ino_t", aka "ino_t" (apart from that "struct ustat")? > > I guess this is mostly a question for s390, which is actively maintained? I couldn't spot any and also gave the patch below a try and my system still boots without any errors. So, as far as I can tell it _should_ be ok to change this. Note that the unusual 32 bit ino_t also recently caused a bug on s390. See commit ebce3eb2f7ef ("ceph: fix inode number handling on arches with 32-bit ino_t"). So getting rid of this would be a good thing. diff --git a/arch/Kconfig b/arch/Kconfig index 24862d15f3a3..383c98e86a70 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -327,6 +327,10 @@ config ARCH_32BIT_OFF_T still support 32-bit off_t. This option is enabled for all such architectures explicitly. +# Selected by 64 bit architectures which have a 32 bit f_tinode in struct ustat +config ARCH_32BIT_USTAT_F_TINODE + bool + config HAVE_ASM_MODVERSIONS bool help diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig index 1f51437d5765..96ce6565890e 100644 --- a/arch/alpha/Kconfig +++ b/arch/alpha/Kconfig @@ -2,6 +2,7 @@ config ALPHA bool default y + select ARCH_32BIT_USTAT_F_TINODE select ARCH_MIGHT_HAVE_PC_PARPORT select ARCH_MIGHT_HAVE_PC_SERIO select ARCH_NO_PREEMPT diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index c72874f09741..434efd9ca0c5 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -58,6 +58,7 @@ config S390 # Note: keep this list sorted alphabetically # imply IMA_SECURE_AND_OR_TRUSTED_BOOT + select ARCH_32BIT_USTAT_F_TINODE select ARCH_BINFMT_ELF_STATE select ARCH_HAS_DEBUG_VM_PGTABLE select ARCH_HAS_DEBUG_WX diff --git a/fs/statfs.c b/fs/statfs.c index 68cb07788750..0ba34c135593 100644 --- a/fs/statfs.c +++ b/fs/statfs.c @@ -255,7 +255,10 @@ SYSCALL_DEFINE2(ustat, unsigned, dev, struct ustat __user *, ubuf) memset(&tmp,0,sizeof(struct ustat)); tmp.f_tfree = sbuf.f_bfree; - tmp.f_tinode = sbuf.f_ffree; + if (IS_ENABLED(CONFIG_ARCH_32BIT_USTAT_F_TINODE)) + tmp.f_tinode = min_t(u64, sbuf.f_ffree, UINT_MAX); + else + tmp.f_tinode = sbuf.f_ffree; return copy_to_user(ubuf, &tmp, sizeof(struct ustat)) ? -EFAULT : 0; } diff --git a/include/linux/types.h b/include/linux/types.h index a147977602b5..1e9d0a2c1dba 100644 --- a/include/linux/types.h +++ b/include/linux/types.h @@ -14,7 +14,7 @@ typedef u32 __kernel_dev_t; typedef __kernel_fd_set fd_set; typedef __kernel_dev_t dev_t; -typedef __kernel_ino_t ino_t; +typedef __kernel_ulong_t ino_t; typedef __kernel_mode_t mode_t; typedef unsigned short umode_t; typedef u32 nlink_t; @@ -189,7 +189,11 @@ struct hlist_node { struct ustat { __kernel_daddr_t f_tfree; - __kernel_ino_t f_tinode; +#ifdef ARCH_HAS_32BIT_F_TINODE + unsigned int f_tinode; +#else + unsigned long f_tinode; +#endif char f_fname[6]; char f_fpack[6]; };