diff mbox series

[v8,8/9] tmpfs: Expose filesystem features via sysfs

Message ID 20241021-tonyk-tmpfs-v8-8-f443d5814194@igalia.com (mailing list archive)
State New
Headers show
Series tmpfs: Add case-insensitive support for tmpfs | expand

Commit Message

André Almeida Oct. 21, 2024, 4:37 p.m. UTC
Expose filesystem features through sysfs, so userspace can query if
tmpfs support casefold.

This follows the same setup as defined by ext4 and f2fs to expose
casefold support to userspace.

Signed-off-by: André Almeida <andrealmeid@igalia.com>
Reviewed-by: Gabriel Krisman Bertazi <krisman@suse.de>
---
 mm/shmem.c | 37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

Comments

Nathan Chancellor Oct. 31, 2024, 5:18 a.m. UTC | #1
Hi André,

On Mon, Oct 21, 2024 at 01:37:24PM -0300, André Almeida wrote:
> Expose filesystem features through sysfs, so userspace can query if
> tmpfs support casefold.
> 
> This follows the same setup as defined by ext4 and f2fs to expose
> casefold support to userspace.
> 
> Signed-off-by: André Almeida <andrealmeid@igalia.com>
> Reviewed-by: Gabriel Krisman Bertazi <krisman@suse.de>
> ---
>  mm/shmem.c | 37 +++++++++++++++++++++++++++++++++++++
>  1 file changed, 37 insertions(+)
> 
> diff --git a/mm/shmem.c b/mm/shmem.c
> index ea01628e443423d82d44277e085b867ab9bf4b28..0739143d1419c732359d3a3c3457c3acb90c5b22 100644
> --- a/mm/shmem.c
> +++ b/mm/shmem.c
> @@ -5546,3 +5546,40 @@ struct page *shmem_read_mapping_page_gfp(struct address_space *mapping,
>  	return page;
>  }
>  EXPORT_SYMBOL_GPL(shmem_read_mapping_page_gfp);
> +
> +#if defined(CONFIG_SYSFS) && defined(CONFIG_TMPFS)
> +#if IS_ENABLED(CONFIG_UNICODE)
> +static DEVICE_STRING_ATTR_RO(casefold, 0444, "supported");
> +#endif
> +
> +static struct attribute *tmpfs_attributes[] = {
> +#if IS_ENABLED(CONFIG_UNICODE)
> +	&dev_attr_casefold.attr.attr,
> +#endif
> +	NULL
> +};
> +
> +static const struct attribute_group tmpfs_attribute_group = {
> +	.attrs = tmpfs_attributes,
> +	.name = "features"
> +};
> +
> +static struct kobject *tmpfs_kobj;
> +
> +static int __init tmpfs_sysfs_init(void)
> +{
> +	int ret;
> +
> +	tmpfs_kobj = kobject_create_and_add("tmpfs", fs_kobj);
> +	if (!tmpfs_kobj)
> +		return -ENOMEM;
> +
> +	ret = sysfs_create_group(tmpfs_kobj, &tmpfs_attribute_group);
> +	if (ret)
> +		kobject_put(tmpfs_kobj);
> +
> +	return ret;
> +}
> +
> +fs_initcall(tmpfs_sysfs_init);
> +#endif /* CONFIG_SYSFS && CONFIG_TMPFS */
> 
> -- 
> 2.47.0
> 

This change as commit 5132f08bd332 ("tmpfs: Expose filesystem features
via sysfs") in -next introduces a kCFI violation when accessing
/sys/fs/tmpfs/features/casefold. An attribute group created with
sysfs_create_group() has ->sysfs_ops() set to kobj_sysfs_ops, which has
a ->show() value of kobj_attr_show(). When kobj_attr_show() goes to call
the attribute's ->show() value after container_of(), there will be a
type mismatch in the case of the casefold attr, as it was defined with a
->show() value of device_show_string() but that does not match the type
of ->show() in 'struct kobj_attribute'.

I can easily reproduce this with the following commands:

  $ printf 'CONFIG_%s=y\n' CFI_CLANG UNICODE >kernel/configs/repro.config

  $ make -skj"$(nproc)" ARCH=arm64 LLVM=1 mrproper virtconfig repro.config Image.gz
  ...

  $ curl -LSs https://github.com/ClangBuiltLinux/boot-utils/releases/download/20230707-182910/arm64-rootfs.cpio.zst | zstd -d >rootfs.cpio

  $ qemu-system-aarch64 \
      -display none \
      -nodefaults \
      -cpu max,pauth-impdef=true \
      -machine virt,gic-version=max,virtualization=true \
      -append 'console=ttyAMA0 earlycon rdinit=/bin/sh' \
      -kernel arch/arm64/boot/Image.gz \
      -initrd rootfs.cpio \
      -m 512m \
      -serial mon:stdio
  ...
  # mount -t sysfs sys /sys
  # cat /sys/fs/tmpfs/features/casefold
  [   70.558496] CFI failure at kobj_attr_show+0x2c/0x4c (target: device_show_string+0x0/0x38; expected type: 0xc527b809)
  [   70.560018] Internal error: Oops - CFI: 00000000f2008228 [#1] PREEMPT SMP
  [   70.560647] Modules linked in:
  [   70.561770] CPU: 0 UID: 0 PID: 46 Comm: cat Not tainted 6.12.0-rc4-00008-g5132f08bd332 #1
  [   70.562429] Hardware name: linux,dummy-virt (DT)
  [   70.562897] pstate: 21402009 (nzCv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--)
  [   70.563377] pc : kobj_attr_show+0x2c/0x4c
  [   70.563674] lr : sysfs_kf_seq_show+0xb4/0x130
  [   70.563987] sp : ffff80008043bac0
  [   70.564236] x29: ffff80008043bac0 x28: 000000007ffff001 x27: 0000000000000000
  [   70.564877] x26: 0000000001000000 x25: 000000007ffff001 x24: 0000000000000001
  [   70.565339] x23: fff000000238a000 x22: ffff9fa31a3996f8 x21: fff00000023fc000
  [   70.565806] x20: fff000000201df80 x19: fff000000238b000 x18: 0000000000000000
  [   70.566273] x17: 00000000c527b809 x16: 00000000df43c25c x15: fff000001fef8200
  [   70.566727] x14: 0000000000000000 x13: fff00000022450f0 x12: 0000000000001000
  [   70.567177] x11: fff00000023fc000 x10: 0000000000000000 x9 : ffff9fa31a18fac4
  [   70.567682] x8 : ffff9fa319badde4 x7 : 0000000000000000 x6 : 000000000000003f
  [   70.568138] x5 : 0000000000000040 x4 : 0000000000000000 x3 : 0000000000000004
  [   70.568585] x2 : fff00000023fc000 x1 : ffff9fa31a881f90 x0 : fff000000201df80
  [   70.569169] Call trace:
  [   70.569389]  kobj_attr_show+0x2c/0x4c
  [   70.569706]  sysfs_kf_seq_show+0xb4/0x130
  [   70.570020]  kernfs_seq_show+0x44/0x54
  [   70.570280]  seq_read_iter+0x14c/0x4b0
  [   70.570543]  kernfs_fop_read_iter+0x60/0x198
  [   70.570820]  copy_splice_read+0x1f0/0x2f4
  [   70.571092]  splice_direct_to_actor+0xf4/0x2e0
  [   70.571376]  do_splice_direct+0x68/0xb8
  [   70.571626]  do_sendfile+0x1e8/0x488
  [   70.571874]  __arm64_sys_sendfile64+0xe0/0x12c
  [   70.572161]  invoke_syscall+0x58/0x114
  [   70.572424]  el0_svc_common+0xa8/0xdc
  [   70.572676]  do_el0_svc+0x1c/0x28
  [   70.572910]  el0_svc+0x38/0x68
  [   70.573132]  el0t_64_sync_handler+0x90/0xfc
  [   70.573394]  el0t_64_sync+0x190/0x19
  [   70.574001] Code: 72970131 72b8a4f1 6b11021f 54000040 (d4304500)
  [   70.574635] ---[ end trace 0000000000000000 ]---

I am not sure if there is a better API exists or if a local copy should
be rolled but I think the current scheme is definitely wrong because
there is no 'struct device' here.

If there is any patch I can test or further information I can provide, I
am more than happy to do so.

Cheers,
Nathan
André Almeida Oct. 31, 2024, 5:31 p.m. UTC | #2
Hi Nathan,

Em 31/10/2024 02:18, Nathan Chancellor escreveu:
> Hi André,
> 
> On Mon, Oct 21, 2024 at 01:37:24PM -0300, André Almeida wrote:
>> Expose filesystem features through sysfs, so userspace can query if
>> tmpfs support casefold.
>>
>> This follows the same setup as defined by ext4 and f2fs to expose
>> casefold support to userspace.
>>
>> Signed-off-by: André Almeida <andrealmeid@igalia.com>
>> Reviewed-by: Gabriel Krisman Bertazi <krisman@suse.de>
>> ---
>>   mm/shmem.c | 37 +++++++++++++++++++++++++++++++++++++
>>   1 file changed, 37 insertions(+)
>>
>> diff --git a/mm/shmem.c b/mm/shmem.c
>> index ea01628e443423d82d44277e085b867ab9bf4b28..0739143d1419c732359d3a3c3457c3acb90c5b22 100644
>> --- a/mm/shmem.c
>> +++ b/mm/shmem.c
>> @@ -5546,3 +5546,40 @@ struct page *shmem_read_mapping_page_gfp(struct address_space *mapping,
>>   	return page;
>>   }
>>   EXPORT_SYMBOL_GPL(shmem_read_mapping_page_gfp);
>> +
>> +#if defined(CONFIG_SYSFS) && defined(CONFIG_TMPFS)
>> +#if IS_ENABLED(CONFIG_UNICODE)
>> +static DEVICE_STRING_ATTR_RO(casefold, 0444, "supported");
>> +#endif
>> +
>> +static struct attribute *tmpfs_attributes[] = {
>> +#if IS_ENABLED(CONFIG_UNICODE)
>> +	&dev_attr_casefold.attr.attr,
>> +#endif
>> +	NULL
>> +};
>> +
>> +static const struct attribute_group tmpfs_attribute_group = {
>> +	.attrs = tmpfs_attributes,
>> +	.name = "features"
>> +};
>> +
>> +static struct kobject *tmpfs_kobj;
>> +
>> +static int __init tmpfs_sysfs_init(void)
>> +{
>> +	int ret;
>> +
>> +	tmpfs_kobj = kobject_create_and_add("tmpfs", fs_kobj);
>> +	if (!tmpfs_kobj)
>> +		return -ENOMEM;
>> +
>> +	ret = sysfs_create_group(tmpfs_kobj, &tmpfs_attribute_group);
>> +	if (ret)
>> +		kobject_put(tmpfs_kobj);
>> +
>> +	return ret;
>> +}
>> +
>> +fs_initcall(tmpfs_sysfs_init);
>> +#endif /* CONFIG_SYSFS && CONFIG_TMPFS */
>>
>> -- 
>> 2.47.0
>>
> 
> This change as commit 5132f08bd332 ("tmpfs: Expose filesystem features
> via sysfs") in -next introduces a kCFI violation when accessing
> /sys/fs/tmpfs/features/casefold. An attribute group created with
> sysfs_create_group() has ->sysfs_ops() set to kobj_sysfs_ops, which has
> a ->show() value of kobj_attr_show(). When kobj_attr_show() goes to call
> the attribute's ->show() value after container_of(), there will be a
> type mismatch in the case of the casefold attr, as it was defined with a
> ->show() value of device_show_string() but that does not match the type
> of ->show() in 'struct kobj_attribute'.
> 
> I can easily reproduce this with the following commands:
> 
>    $ printf 'CONFIG_%s=y\n' CFI_CLANG UNICODE >kernel/configs/repro.config
> 
>    $ make -skj"$(nproc)" ARCH=arm64 LLVM=1 mrproper virtconfig repro.config Image.gz
>    ...
> 
>    $ curl -LSs https://github.com/ClangBuiltLinux/boot-utils/releases/download/20230707-182910/arm64-rootfs.cpio.zst | zstd -d >rootfs.cpio
> 
>    $ qemu-system-aarch64 \
>        -display none \
>        -nodefaults \
>        -cpu max,pauth-impdef=true \
>        -machine virt,gic-version=max,virtualization=true \
>        -append 'console=ttyAMA0 earlycon rdinit=/bin/sh' \
>        -kernel arch/arm64/boot/Image.gz \
>        -initrd rootfs.cpio \
>        -m 512m \
>        -serial mon:stdio
>    ...
>    # mount -t sysfs sys /sys
>    # cat /sys/fs/tmpfs/features/casefold
>    [   70.558496] CFI failure at kobj_attr_show+0x2c/0x4c (target: device_show_string+0x0/0x38; expected type: 0xc527b809)
>    [   70.560018] Internal error: Oops - CFI: 00000000f2008228 [#1] PREEMPT SMP
>    [   70.560647] Modules linked in:
>    [   70.561770] CPU: 0 UID: 0 PID: 46 Comm: cat Not tainted 6.12.0-rc4-00008-g5132f08bd332 #1
>    [   70.562429] Hardware name: linux,dummy-virt (DT)
>    [   70.562897] pstate: 21402009 (nzCv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--)
>    [   70.563377] pc : kobj_attr_show+0x2c/0x4c
>    [   70.563674] lr : sysfs_kf_seq_show+0xb4/0x130
>    [   70.563987] sp : ffff80008043bac0
>    [   70.564236] x29: ffff80008043bac0 x28: 000000007ffff001 x27: 0000000000000000
>    [   70.564877] x26: 0000000001000000 x25: 000000007ffff001 x24: 0000000000000001
>    [   70.565339] x23: fff000000238a000 x22: ffff9fa31a3996f8 x21: fff00000023fc000
>    [   70.565806] x20: fff000000201df80 x19: fff000000238b000 x18: 0000000000000000
>    [   70.566273] x17: 00000000c527b809 x16: 00000000df43c25c x15: fff000001fef8200
>    [   70.566727] x14: 0000000000000000 x13: fff00000022450f0 x12: 0000000000001000
>    [   70.567177] x11: fff00000023fc000 x10: 0000000000000000 x9 : ffff9fa31a18fac4
>    [   70.567682] x8 : ffff9fa319badde4 x7 : 0000000000000000 x6 : 000000000000003f
>    [   70.568138] x5 : 0000000000000040 x4 : 0000000000000000 x3 : 0000000000000004
>    [   70.568585] x2 : fff00000023fc000 x1 : ffff9fa31a881f90 x0 : fff000000201df80
>    [   70.569169] Call trace:
>    [   70.569389]  kobj_attr_show+0x2c/0x4c
>    [   70.569706]  sysfs_kf_seq_show+0xb4/0x130
>    [   70.570020]  kernfs_seq_show+0x44/0x54
>    [   70.570280]  seq_read_iter+0x14c/0x4b0
>    [   70.570543]  kernfs_fop_read_iter+0x60/0x198
>    [   70.570820]  copy_splice_read+0x1f0/0x2f4
>    [   70.571092]  splice_direct_to_actor+0xf4/0x2e0
>    [   70.571376]  do_splice_direct+0x68/0xb8
>    [   70.571626]  do_sendfile+0x1e8/0x488
>    [   70.571874]  __arm64_sys_sendfile64+0xe0/0x12c
>    [   70.572161]  invoke_syscall+0x58/0x114
>    [   70.572424]  el0_svc_common+0xa8/0xdc
>    [   70.572676]  do_el0_svc+0x1c/0x28
>    [   70.572910]  el0_svc+0x38/0x68
>    [   70.573132]  el0t_64_sync_handler+0x90/0xfc
>    [   70.573394]  el0t_64_sync+0x190/0x19
>    [   70.574001] Code: 72970131 72b8a4f1 6b11021f 54000040 (d4304500)
>    [   70.574635] ---[ end trace 0000000000000000 ]---
> 
> I am not sure if there is a better API exists or if a local copy should
> be rolled but I think the current scheme is definitely wrong because
> there is no 'struct device' here.
> 

Thank you for the report, I'm trying to fix it, it seems I have used 
something for device drivers in a filesystem. I wonder how btrfs doesn't 
get this error, since tmpfs_sysfs_init() is very similar to 
btrfs_init_sysfs().

> If there is any patch I can test or further information I can provide, I
> am more than happy to do so.
> 
> Cheers,
> Nathan
Nathan Chancellor Oct. 31, 2024, 6:13 p.m. UTC | #3
On Thu, Oct 31, 2024 at 02:31:21PM -0300, André Almeida wrote:
> Hi Nathan,
> 
> Em 31/10/2024 02:18, Nathan Chancellor escreveu:
> > Hi André,
> > 
> > On Mon, Oct 21, 2024 at 01:37:24PM -0300, André Almeida wrote:
> > > Expose filesystem features through sysfs, so userspace can query if
> > > tmpfs support casefold.
> > > 
> > > This follows the same setup as defined by ext4 and f2fs to expose
> > > casefold support to userspace.
> > > 
> > > Signed-off-by: André Almeida <andrealmeid@igalia.com>
> > > Reviewed-by: Gabriel Krisman Bertazi <krisman@suse.de>
> > > ---
> > >   mm/shmem.c | 37 +++++++++++++++++++++++++++++++++++++
> > >   1 file changed, 37 insertions(+)
> > > 
> > > diff --git a/mm/shmem.c b/mm/shmem.c
> > > index ea01628e443423d82d44277e085b867ab9bf4b28..0739143d1419c732359d3a3c3457c3acb90c5b22 100644
> > > --- a/mm/shmem.c
> > > +++ b/mm/shmem.c
> > > @@ -5546,3 +5546,40 @@ struct page *shmem_read_mapping_page_gfp(struct address_space *mapping,
> > >   	return page;
> > >   }
> > >   EXPORT_SYMBOL_GPL(shmem_read_mapping_page_gfp);
> > > +
> > > +#if defined(CONFIG_SYSFS) && defined(CONFIG_TMPFS)
> > > +#if IS_ENABLED(CONFIG_UNICODE)
> > > +static DEVICE_STRING_ATTR_RO(casefold, 0444, "supported");
> > > +#endif
> > > +
> > > +static struct attribute *tmpfs_attributes[] = {
> > > +#if IS_ENABLED(CONFIG_UNICODE)
> > > +	&dev_attr_casefold.attr.attr,
> > > +#endif
> > > +	NULL
> > > +};
> > > +
> > > +static const struct attribute_group tmpfs_attribute_group = {
> > > +	.attrs = tmpfs_attributes,
> > > +	.name = "features"
> > > +};
> > > +
> > > +static struct kobject *tmpfs_kobj;
> > > +
> > > +static int __init tmpfs_sysfs_init(void)
> > > +{
> > > +	int ret;
> > > +
> > > +	tmpfs_kobj = kobject_create_and_add("tmpfs", fs_kobj);
> > > +	if (!tmpfs_kobj)
> > > +		return -ENOMEM;
> > > +
> > > +	ret = sysfs_create_group(tmpfs_kobj, &tmpfs_attribute_group);
> > > +	if (ret)
> > > +		kobject_put(tmpfs_kobj);
> > > +
> > > +	return ret;
> > > +}
> > > +
> > > +fs_initcall(tmpfs_sysfs_init);
> > > +#endif /* CONFIG_SYSFS && CONFIG_TMPFS */
> > > 
> > > -- 
> > > 2.47.0
> > > 
> > 
> > This change as commit 5132f08bd332 ("tmpfs: Expose filesystem features
> > via sysfs") in -next introduces a kCFI violation when accessing
> > /sys/fs/tmpfs/features/casefold. An attribute group created with
> > sysfs_create_group() has ->sysfs_ops() set to kobj_sysfs_ops, which has
> > a ->show() value of kobj_attr_show(). When kobj_attr_show() goes to call
> > the attribute's ->show() value after container_of(), there will be a
> > type mismatch in the case of the casefold attr, as it was defined with a
> > ->show() value of device_show_string() but that does not match the type
> > of ->show() in 'struct kobj_attribute'.
> > 
> > I can easily reproduce this with the following commands:
> > 
> >    $ printf 'CONFIG_%s=y\n' CFI_CLANG UNICODE >kernel/configs/repro.config
> > 
> >    $ make -skj"$(nproc)" ARCH=arm64 LLVM=1 mrproper virtconfig repro.config Image.gz
> >    ...
> > 
> >    $ curl -LSs https://github.com/ClangBuiltLinux/boot-utils/releases/download/20230707-182910/arm64-rootfs.cpio.zst | zstd -d >rootfs.cpio
> > 
> >    $ qemu-system-aarch64 \
> >        -display none \
> >        -nodefaults \
> >        -cpu max,pauth-impdef=true \
> >        -machine virt,gic-version=max,virtualization=true \
> >        -append 'console=ttyAMA0 earlycon rdinit=/bin/sh' \
> >        -kernel arch/arm64/boot/Image.gz \
> >        -initrd rootfs.cpio \
> >        -m 512m \
> >        -serial mon:stdio
> >    ...
> >    # mount -t sysfs sys /sys
> >    # cat /sys/fs/tmpfs/features/casefold
> >    [   70.558496] CFI failure at kobj_attr_show+0x2c/0x4c (target: device_show_string+0x0/0x38; expected type: 0xc527b809)
> >    [   70.560018] Internal error: Oops - CFI: 00000000f2008228 [#1] PREEMPT SMP
> >    [   70.560647] Modules linked in:
> >    [   70.561770] CPU: 0 UID: 0 PID: 46 Comm: cat Not tainted 6.12.0-rc4-00008-g5132f08bd332 #1
> >    [   70.562429] Hardware name: linux,dummy-virt (DT)
> >    [   70.562897] pstate: 21402009 (nzCv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--)
> >    [   70.563377] pc : kobj_attr_show+0x2c/0x4c
> >    [   70.563674] lr : sysfs_kf_seq_show+0xb4/0x130
> >    [   70.563987] sp : ffff80008043bac0
> >    [   70.564236] x29: ffff80008043bac0 x28: 000000007ffff001 x27: 0000000000000000
> >    [   70.564877] x26: 0000000001000000 x25: 000000007ffff001 x24: 0000000000000001
> >    [   70.565339] x23: fff000000238a000 x22: ffff9fa31a3996f8 x21: fff00000023fc000
> >    [   70.565806] x20: fff000000201df80 x19: fff000000238b000 x18: 0000000000000000
> >    [   70.566273] x17: 00000000c527b809 x16: 00000000df43c25c x15: fff000001fef8200
> >    [   70.566727] x14: 0000000000000000 x13: fff00000022450f0 x12: 0000000000001000
> >    [   70.567177] x11: fff00000023fc000 x10: 0000000000000000 x9 : ffff9fa31a18fac4
> >    [   70.567682] x8 : ffff9fa319badde4 x7 : 0000000000000000 x6 : 000000000000003f
> >    [   70.568138] x5 : 0000000000000040 x4 : 0000000000000000 x3 : 0000000000000004
> >    [   70.568585] x2 : fff00000023fc000 x1 : ffff9fa31a881f90 x0 : fff000000201df80
> >    [   70.569169] Call trace:
> >    [   70.569389]  kobj_attr_show+0x2c/0x4c
> >    [   70.569706]  sysfs_kf_seq_show+0xb4/0x130
> >    [   70.570020]  kernfs_seq_show+0x44/0x54
> >    [   70.570280]  seq_read_iter+0x14c/0x4b0
> >    [   70.570543]  kernfs_fop_read_iter+0x60/0x198
> >    [   70.570820]  copy_splice_read+0x1f0/0x2f4
> >    [   70.571092]  splice_direct_to_actor+0xf4/0x2e0
> >    [   70.571376]  do_splice_direct+0x68/0xb8
> >    [   70.571626]  do_sendfile+0x1e8/0x488
> >    [   70.571874]  __arm64_sys_sendfile64+0xe0/0x12c
> >    [   70.572161]  invoke_syscall+0x58/0x114
> >    [   70.572424]  el0_svc_common+0xa8/0xdc
> >    [   70.572676]  do_el0_svc+0x1c/0x28
> >    [   70.572910]  el0_svc+0x38/0x68
> >    [   70.573132]  el0t_64_sync_handler+0x90/0xfc
> >    [   70.573394]  el0t_64_sync+0x190/0x19
> >    [   70.574001] Code: 72970131 72b8a4f1 6b11021f 54000040 (d4304500)
> >    [   70.574635] ---[ end trace 0000000000000000 ]---
> > 
> > I am not sure if there is a better API exists or if a local copy should
> > be rolled but I think the current scheme is definitely wrong because
> > there is no 'struct device' here.
> > 
> 
> Thank you for the report, I'm trying to fix it, it seems I have used
> something for device drivers in a filesystem. I wonder how btrfs doesn't get
> this error, since tmpfs_sysfs_init() is very similar to btrfs_init_sysfs().

Upon a quick glance, it looks like all of the btrfs sysfs functions
properly match the ->show() and ->store() type in kobj_attribute, so
there is no type mismatch when they are called indirectly.

Cheers,
Nathan
André Almeida Oct. 31, 2024, 7:11 p.m. UTC | #4
Em 31/10/2024 14:31, André Almeida escreveu:
> Hi Nathan,
> 
> Em 31/10/2024 02:18, Nathan Chancellor escreveu:
>> Hi André,
>>

[...]

>> If there is any patch I can test or further information I can provide, I
>> am more than happy to do so.
>>

I found the issue, was just the DEVICE_ macro that I wasn't supposed to 
use inside of tmpfs, this diff solved the error for me, I will send a 
proper patch in a moment:

-- >8 --

diff --git a/mm/shmem.c b/mm/shmem.c
index 971e6f1184a5..db52c34d5020 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -5551,12 +5551,21 @@ EXPORT_SYMBOL_GPL(shmem_read_mapping_page_gfp);

  #if defined(CONFIG_SYSFS) && defined(CONFIG_TMPFS)
  #if IS_ENABLED(CONFIG_UNICODE)
-static DEVICE_STRING_ATTR_RO(casefold, 0444, "supported");
+static ssize_t casefold_show(struct kobject *kobj, struct 
kobj_attribute *a,
+                       char *buf)
+{
+               return sysfs_emit(buf, "supported\n");
+}
+static struct kobj_attribute tmpfs_attr_casefold = {
+               .attr = { .name = "casefold", .mode = 0444 },
+               .show = casefold_show,
+               .store = NULL,
+};
  #endif

  static struct attribute *tmpfs_attributes[] = {
  #if IS_ENABLED(CONFIG_UNICODE)
-       &dev_attr_casefold.attr.attr,
+       &tmpfs_attr_casefold.attr,
  #endif
         NULL
  };
diff mbox series

Patch

diff --git a/mm/shmem.c b/mm/shmem.c
index ea01628e443423d82d44277e085b867ab9bf4b28..0739143d1419c732359d3a3c3457c3acb90c5b22 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -5546,3 +5546,40 @@  struct page *shmem_read_mapping_page_gfp(struct address_space *mapping,
 	return page;
 }
 EXPORT_SYMBOL_GPL(shmem_read_mapping_page_gfp);
+
+#if defined(CONFIG_SYSFS) && defined(CONFIG_TMPFS)
+#if IS_ENABLED(CONFIG_UNICODE)
+static DEVICE_STRING_ATTR_RO(casefold, 0444, "supported");
+#endif
+
+static struct attribute *tmpfs_attributes[] = {
+#if IS_ENABLED(CONFIG_UNICODE)
+	&dev_attr_casefold.attr.attr,
+#endif
+	NULL
+};
+
+static const struct attribute_group tmpfs_attribute_group = {
+	.attrs = tmpfs_attributes,
+	.name = "features"
+};
+
+static struct kobject *tmpfs_kobj;
+
+static int __init tmpfs_sysfs_init(void)
+{
+	int ret;
+
+	tmpfs_kobj = kobject_create_and_add("tmpfs", fs_kobj);
+	if (!tmpfs_kobj)
+		return -ENOMEM;
+
+	ret = sysfs_create_group(tmpfs_kobj, &tmpfs_attribute_group);
+	if (ret)
+		kobject_put(tmpfs_kobj);
+
+	return ret;
+}
+
+fs_initcall(tmpfs_sysfs_init);
+#endif /* CONFIG_SYSFS && CONFIG_TMPFS */