[PATCH 02/61] vfs: change i_ino from unsigned long to u64

Jeff Layton posted 61 patches 1 month, 1 week ago
There is a newer version of this series
[PATCH 02/61] vfs: change i_ino from unsigned long to u64
Posted by Jeff Layton 1 month, 1 week ago
Change the type of i_ino in struct inode from unsigned long to u64.

On 64-bit architectures, unsigned long is already 64 bits, so this is
effectively a type alias change with no runtime impact. On 32-bit
architectures, this widens i_ino from 32 to 64 bits, allowing
filesystems like NFS, CIFS, XFS, Ceph, and FUSE to store their native
64-bit inode numbers without folding/hashing.

The VFS already handles 64-bit inode numbers in kstat.ino (u64) and
statx.stx_ino (__u64). The existing overflow checks in cp_new_stat(),
cp_old_stat(), and cp_compat_stat() handle narrowing to 32-bit st_ino
with -EOVERFLOW, so userspace ABI is preserved.

struct inode will grow by 4 bytes on 32-bit architectures.

Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
 include/linux/fs.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/fs.h b/include/linux/fs.h
index dfa1f475b1c480c503ab6f00e891aa9b051607fa..097443bf12e289c347651e5f3da5b67eb6b53121 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -783,7 +783,7 @@ struct inode {
 #endif
 
 	/* Stat data, not accessed from path walking */
-	unsigned long		i_ino;
+	u64			i_ino;
 	/*
 	 * Filesystems may only read i_nlink directly.  They shall use the
 	 * following functions for modification:

-- 
2.53.0
Re: [PATCH 02/61] vfs: change i_ino from unsigned long to u64
Posted by Mathieu Desnoyers 1 month, 1 week ago
On 2026-02-26 10:55, Jeff Layton wrote:
> Change the type of i_ino in struct inode from unsigned long to u64.
> 
> On 64-bit architectures, unsigned long is already 64 bits, so this is
> effectively a type alias change with no runtime impact. On 32-bit
> architectures, this widens i_ino from 32 to 64 bits, allowing
> filesystems like NFS, CIFS, XFS, Ceph, and FUSE to store their native
> 64-bit inode numbers without folding/hashing.
> 
> The VFS already handles 64-bit inode numbers in kstat.ino (u64) and
> statx.stx_ino (__u64). The existing overflow checks in cp_new_stat(),
> cp_old_stat(), and cp_compat_stat() handle narrowing to 32-bit st_ino
> with -EOVERFLOW, so userspace ABI is preserved.
> 
> struct inode will grow by 4 bytes on 32-bit architectures.

Changing this type first without changing its associated format strings
breaks git bisect.

One alternative would be to introduce something like the PRIu64 macro
but for printing inode values. This would allow gradually introducing
the change without breaking the world as you do so.

Thanks,

Mathieu

-- 
Mathieu Desnoyers
EfficiOS Inc.
https://www.efficios.com
Re: [PATCH 02/61] vfs: change i_ino from unsigned long to u64
Posted by David Laight 1 month, 1 week ago
On Thu, 26 Feb 2026 11:16:50 -0500
Mathieu Desnoyers <mathieu.desnoyers@efficios.com> wrote:

> On 2026-02-26 10:55, Jeff Layton wrote:
> > Change the type of i_ino in struct inode from unsigned long to u64.
> > 
> > On 64-bit architectures, unsigned long is already 64 bits, so this is
> > effectively a type alias change with no runtime impact. On 32-bit
> > architectures, this widens i_ino from 32 to 64 bits, allowing
> > filesystems like NFS, CIFS, XFS, Ceph, and FUSE to store their native
> > 64-bit inode numbers without folding/hashing.
> > 
> > The VFS already handles 64-bit inode numbers in kstat.ino (u64) and
> > statx.stx_ino (__u64). The existing overflow checks in cp_new_stat(),
> > cp_old_stat(), and cp_compat_stat() handle narrowing to 32-bit st_ino
> > with -EOVERFLOW, so userspace ABI is preserved.
> > 
> > struct inode will grow by 4 bytes on 32-bit architectures.  
> 
> Changing this type first without changing its associated format strings
> breaks git bisect.

Or find all the format strings, change to %llu and add (u64) casts.
That should compile and run in both 32bit and 64bit.
At the end you could delete the casts.

	David

> 
> One alternative would be to introduce something like the PRIu64 macro
> but for printing inode values. This would allow gradually introducing
> the change without breaking the world as you do so.
> 
> Thanks,
> 
> Mathieu
>
Re: [PATCH 02/61] vfs: change i_ino from unsigned long to u64
Posted by Jeff Layton 1 month, 1 week ago
On Thu, 2026-02-26 at 11:16 -0500, Mathieu Desnoyers wrote:
> On 2026-02-26 10:55, Jeff Layton wrote:
> > Change the type of i_ino in struct inode from unsigned long to u64.
> > 
> > On 64-bit architectures, unsigned long is already 64 bits, so this is
> > effectively a type alias change with no runtime impact. On 32-bit
> > architectures, this widens i_ino from 32 to 64 bits, allowing
> > filesystems like NFS, CIFS, XFS, Ceph, and FUSE to store their native
> > 64-bit inode numbers without folding/hashing.
> > 
> > The VFS already handles 64-bit inode numbers in kstat.ino (u64) and
> > statx.stx_ino (__u64). The existing overflow checks in cp_new_stat(),
> > cp_old_stat(), and cp_compat_stat() handle narrowing to 32-bit st_ino
> > with -EOVERFLOW, so userspace ABI is preserved.
> > 
> > struct inode will grow by 4 bytes on 32-bit architectures.
> 
> Changing this type first without changing its associated format strings
> breaks git bisect.
> 
> One alternative would be to introduce something like the PRIu64 macro
> but for printing inode values. This would allow gradually introducing
> the change without breaking the world as you do so.
> 
> 

True, but it makes all of the format strings even harder to read. After
the conversion, we could go back and eliminate the macro though and it
would keep things more bisectable. I'm not sure what to do about
tracepoints though. I guess we could declare a new typedef and change
its definition when i_ino's type changes?

I'll let others chime in first, but I'm open to going back and doing it
that way if we don't want to live with the compiler warnings during a
bisect.

-- 
Jeff Layton <jlayton@kernel.org>
Re: [PATCH 02/61] vfs: change i_ino from unsigned long to u64
Posted by Mathieu Desnoyers 1 month, 1 week ago
On 2026-02-26 11:35, Jeff Layton wrote:
> On Thu, 2026-02-26 at 11:16 -0500, Mathieu Desnoyers wrote:
>> On 2026-02-26 10:55, Jeff Layton wrote:
>>> Change the type of i_ino in struct inode from unsigned long to u64.
>>>
>>> On 64-bit architectures, unsigned long is already 64 bits, so this is
>>> effectively a type alias change with no runtime impact. On 32-bit
>>> architectures, this widens i_ino from 32 to 64 bits, allowing
>>> filesystems like NFS, CIFS, XFS, Ceph, and FUSE to store their native
>>> 64-bit inode numbers without folding/hashing.
>>>
>>> The VFS already handles 64-bit inode numbers in kstat.ino (u64) and
>>> statx.stx_ino (__u64). The existing overflow checks in cp_new_stat(),
>>> cp_old_stat(), and cp_compat_stat() handle narrowing to 32-bit st_ino
>>> with -EOVERFLOW, so userspace ABI is preserved.
>>>
>>> struct inode will grow by 4 bytes on 32-bit architectures.
>>
>> Changing this type first without changing its associated format strings
>> breaks git bisect.
>>
>> One alternative would be to introduce something like the PRIu64 macro
>> but for printing inode values. This would allow gradually introducing
>> the change without breaking the world as you do so.
>>
>>
> 
> True, but it makes all of the format strings even harder to read. After
> the conversion, we could go back and eliminate the macro though and it
> would keep things more bisectable. I'm not sure what to do about
> tracepoints though. I guess we could declare a new typedef and change
> its definition when i_ino's type changes?

For tracepoints there are two things: a TP_printk format string (which
would be handled by a new pretty printing macro similar to PRIu64), and
the type used within TP_STRUCT__entry. I don't see why you'd need to
change from ino_t to u64 there. The conversion will happen when you flip
the ino_t typedef from unsigned long to u64.

> 
> I'll let others chime in first, but I'm open to going back and doing it
> that way if we don't want to live with the compiler warnings during a
> bisect.

On 32-bit archs, I suspect it will do more than emit compiler warnings.
Trying to boot a kernel in the middle of the series is likely to lead to
interesting inode value printout results.

Thanks,

Mathieu

-- 
Mathieu Desnoyers
EfficiOS Inc.
https://www.efficios.com
Re: [PATCH 02/61] vfs: change i_ino from unsigned long to u64
Posted by Jeff Layton 1 month, 1 week ago
On Thu, 2026-02-26 at 11:40 -0500, Mathieu Desnoyers wrote:
> On 2026-02-26 11:35, Jeff Layton wrote:
> > On Thu, 2026-02-26 at 11:16 -0500, Mathieu Desnoyers wrote:
> > > On 2026-02-26 10:55, Jeff Layton wrote:
> > > > Change the type of i_ino in struct inode from unsigned long to u64.
> > > > 
> > > > On 64-bit architectures, unsigned long is already 64 bits, so this is
> > > > effectively a type alias change with no runtime impact. On 32-bit
> > > > architectures, this widens i_ino from 32 to 64 bits, allowing
> > > > filesystems like NFS, CIFS, XFS, Ceph, and FUSE to store their native
> > > > 64-bit inode numbers without folding/hashing.
> > > > 
> > > > The VFS already handles 64-bit inode numbers in kstat.ino (u64) and
> > > > statx.stx_ino (__u64). The existing overflow checks in cp_new_stat(),
> > > > cp_old_stat(), and cp_compat_stat() handle narrowing to 32-bit st_ino
> > > > with -EOVERFLOW, so userspace ABI is preserved.
> > > > 
> > > > struct inode will grow by 4 bytes on 32-bit architectures.
> > > 
> > > Changing this type first without changing its associated format strings
> > > breaks git bisect.
> > > 
> > > One alternative would be to introduce something like the PRIu64 macro
> > > but for printing inode values. This would allow gradually introducing
> > > the change without breaking the world as you do so.
> > > 
> > > 
> > 
> > True, but it makes all of the format strings even harder to read. After
> > the conversion, we could go back and eliminate the macro though and it
> > would keep things more bisectable. I'm not sure what to do about
> > tracepoints though. I guess we could declare a new typedef and change
> > its definition when i_ino's type changes?
> 
> For tracepoints there are two things: a TP_printk format string (which
> would be handled by a new pretty printing macro similar to PRIu64), and
> the type used within TP_STRUCT__entry. I don't see why you'd need to
> change from ino_t to u64 there. The conversion will happen when you flip
> the ino_t typedef from unsigned long to u64.
> 

My worry here is that ino_t is a UAPI type, and I don't think we can
change it there. I think we'll need a new (kernel-internal) typedef
just for this.

> > 
> > I'll let others chime in first, but I'm open to going back and doing it
> > that way if we don't want to live with the compiler warnings during a
> > bisect.
> 
> On 32-bit archs, I suspect it will do more than emit compiler warnings.
> Trying to boot a kernel in the middle of the series is likely to lead to
> interesting inode value printout results.
> 

Definitely. None of that would be trustworthy in the middle of the
series.
-- 
Jeff Layton <jlayton@kernel.org>
Re: [PATCH 02/61] vfs: change i_ino from unsigned long to u64
Posted by Jan Kara 1 month, 1 week ago
On Thu 26-02-26 11:45:16, Jeff Layton wrote:
> On Thu, 2026-02-26 at 11:40 -0500, Mathieu Desnoyers wrote:
> > On 2026-02-26 11:35, Jeff Layton wrote:
> > > 
> > > I'll let others chime in first, but I'm open to going back and doing it
> > > that way if we don't want to live with the compiler warnings during a
> > > bisect.
> > 
> > On 32-bit archs, I suspect it will do more than emit compiler warnings.
> > Trying to boot a kernel in the middle of the series is likely to lead to
> > interesting inode value printout results.
> > 
> 
> Definitely. None of that would be trustworthy in the middle of the
> series.

Yeah, I think defining kino_t in the beginning as unsigned long, convert
everything (including special format string specifier) to it, then switch
it to u64 and finally just 'sed-out' the format string specifier in the
final patch shouldn't be harder than what you do here and should keep
bisectability?

								Honza
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR
Re: [PATCH 02/61] vfs: change i_ino from unsigned long to u64
Posted by Jeff Layton 1 month, 1 week ago
On Thu, 2026-02-26 at 18:19 +0100, Jan Kara wrote:
> On Thu 26-02-26 11:45:16, Jeff Layton wrote:
> > On Thu, 2026-02-26 at 11:40 -0500, Mathieu Desnoyers wrote:
> > > On 2026-02-26 11:35, Jeff Layton wrote:
> > > > 
> > > > I'll let others chime in first, but I'm open to going back and doing it
> > > > that way if we don't want to live with the compiler warnings during a
> > > > bisect.
> > > 
> > > On 32-bit archs, I suspect it will do more than emit compiler warnings.
> > > Trying to boot a kernel in the middle of the series is likely to lead to
> > > interesting inode value printout results.
> > > 
> > 
> > Definitely. None of that would be trustworthy in the middle of the
> > series.
> 
> Yeah, I think defining kino_t in the beginning as unsigned long, convert
> everything (including special format string specifier) to it, then switch
> it to u64 and finally just 'sed-out' the format string specifier in the
> final patch shouldn't be harder than what you do here and should keep
> bisectability?
> 

Ok. I'll look at doing it in a way that doesn't break bisectability.

-- 
Jeff Layton <jlayton@kernel.org>
Re: [PATCH 02/61] vfs: change i_ino from unsigned long to u64
Posted by Mathieu Desnoyers 1 month, 1 week ago
On 2026-02-26 11:45, Jeff Layton wrote:
> On Thu, 2026-02-26 at 11:40 -0500, Mathieu Desnoyers wrote:
>> On 2026-02-26 11:35, Jeff Layton wrote:
>>> On Thu, 2026-02-26 at 11:16 -0500, Mathieu Desnoyers wrote:
>>>> On 2026-02-26 10:55, Jeff Layton wrote:
>>>>> Change the type of i_ino in struct inode from unsigned long to u64.
>>>>>
>>>>> On 64-bit architectures, unsigned long is already 64 bits, so this is
>>>>> effectively a type alias change with no runtime impact. On 32-bit
>>>>> architectures, this widens i_ino from 32 to 64 bits, allowing
>>>>> filesystems like NFS, CIFS, XFS, Ceph, and FUSE to store their native
>>>>> 64-bit inode numbers without folding/hashing.
>>>>>
>>>>> The VFS already handles 64-bit inode numbers in kstat.ino (u64) and
>>>>> statx.stx_ino (__u64). The existing overflow checks in cp_new_stat(),
>>>>> cp_old_stat(), and cp_compat_stat() handle narrowing to 32-bit st_ino
>>>>> with -EOVERFLOW, so userspace ABI is preserved.
>>>>>
>>>>> struct inode will grow by 4 bytes on 32-bit architectures.
>>>>
>>>> Changing this type first without changing its associated format strings
>>>> breaks git bisect.
>>>>
>>>> One alternative would be to introduce something like the PRIu64 macro
>>>> but for printing inode values. This would allow gradually introducing
>>>> the change without breaking the world as you do so.
>>>>
>>>>
>>>
>>> True, but it makes all of the format strings even harder to read. After
>>> the conversion, we could go back and eliminate the macro though and it
>>> would keep things more bisectable. I'm not sure what to do about
>>> tracepoints though. I guess we could declare a new typedef and change
>>> its definition when i_ino's type changes?
>>
>> For tracepoints there are two things: a TP_printk format string (which
>> would be handled by a new pretty printing macro similar to PRIu64), and
>> the type used within TP_STRUCT__entry. I don't see why you'd need to
>> change from ino_t to u64 there. The conversion will happen when you flip
>> the ino_t typedef from unsigned long to u64.
>>
> 
> My worry here is that ino_t is a UAPI type, and I don't think we can
> change it there. I think we'll need a new (kernel-internal) typedef
> just for this.

If ino_t is UAPI then it cannot be changed, but you can introduce a new
kino_t or whatever naming is appropriate.

Thanks,

Mathieu

-- 
Mathieu Desnoyers
EfficiOS Inc.
https://www.efficios.com