Re: [PATCH 10/11] fs/ntfs3: Remove cached label from sbi
From: Nathan Chancellor
Date: Mon Apr 22 2024 - 16:42:34 EST
Hi Konstantin,
On Wed, Apr 17, 2024 at 04:09:00PM +0300, Konstantin Komarov wrote:
> Add more checks using $AttrDef.
>
> Signed-off-by: Konstantin Komarov <almaz.alexandrovich@xxxxxxxxxxxxxxxxxxxx>
<snip>
> diff --git a/fs/ntfs3/super.c b/fs/ntfs3/super.c
> index 8beefbca5769..dae961d2d6f8 100644
> --- a/fs/ntfs3/super.c
> +++ b/fs/ntfs3/super.c
> @@ -481,11 +481,39 @@ static int ntfs3_volinfo_open(struct inode *inode,
> struct file *file)
> /* read /proc/fs/ntfs3/<dev>/label */
> static int ntfs3_label_show(struct seq_file *m, void *o)
> {
> + int len;
> struct super_block *sb = m->private;
> struct ntfs_sb_info *sbi = sb->s_fs_info;
> + struct ATTRIB *attr;
> + u8 *label = kmalloc(PAGE_SIZE, GFP_NOFS);
> +
> + if (!label)
> + return -ENOMEM;
> +
> + attr = ni_find_attr(sbi->volume.ni, NULL, NULL, ATTR_LABEL, NULL, 0,
> + NULL, NULL);
> +
> + if (!attr) {
> + /* It is ok if no ATTR_LABEL */
> + label[0] = 0;
> + len = 0;
> + } else if (!attr_check(attr, sbi, sbi->volume.ni)) {
> + len = sprintf(label, "%pg: failed to get label", sb->s_bdev);
> + } else {
> + len = ntfs_utf16_to_nls(sbi, resident_data(attr),
> + le32_to_cpu(attr->res.data_size) >> 1,
> + label, PAGE_SIZE);
> + if (len < 0) {
> + label[0] = 0;
> + len = 0;
> + } else if (len >= PAGE_SIZE) {
> + len = PAGE_SIZE - 1;
> + }
> + }
>
> - seq_printf(m, "%s\n", sbi->volume.label);
> + seq_printf(m, "%.*s\n", len, label);
>
> + kfree(label);
> return 0;
> }
>
> @@ -1210,25 +1238,6 @@ static int ntfs_fill_super(struct super_block *sb,
> struct fs_context *fc)
>
> ni = ntfs_i(inode);
>
> - /* Load and save label (not necessary). */
> - attr = ni_find_attr(ni, NULL, NULL, ATTR_LABEL, NULL, 0, NULL, NULL);
> -
> - if (!attr) {
> - /* It is ok if no ATTR_LABEL */
> - } else if (!attr->non_res && !is_attr_ext(attr)) {
> - /* $AttrDef allows labels to be up to 128 symbols. */
> - err = utf16s_to_utf8s(resident_data(attr),
> - le32_to_cpu(attr->res.data_size) >> 1,
> - UTF16_LITTLE_ENDIAN, sbi->volume.label,
> - sizeof(sbi->volume.label));
> - if (err < 0)
> - sbi->volume.label[0] = 0;
> - } else {
> - /* Should we break mounting here? */
> - //err = -EINVAL;
> - //goto put_inode_out;
> - }
> -
The attr initialization above causes the use in the ni_find_attr() to be
uninitialized, which results in the following clang warning (or error
when CONFIG_WERROR is enabled):
fs/ntfs3/super.c:1247:26: error: variable 'attr' is uninitialized when used here [-Werror,-Wuninitialized]
1247 | attr = ni_find_attr(ni, attr, NULL, ATTR_VOL_INFO, NULL, 0, NULL, NULL);
| ^~~~
fs/ntfs3/super.c:1192:21: note: initialize the variable 'attr' to silence this warning
1192 | struct ATTRIB *attr;
| ^
| = NULL
1 error generated.
Please either fix this quickly (as this isn't the first time an ntfs3
change has broken us for some time in -next for a similar reason [1]) or
remove this series from -next. Given the issues that Johan has brought
up in other comments in this thread, I feel like the latter may be
better, as this series is clearly not ready for Linus (which is one of
-next's general requirements AFAIUI).
> attr = ni_find_attr(ni, attr, NULL, ATTR_VOL_INFO, NULL, 0, NULL,
> NULL);
> if (!attr || is_attr_ext(attr) ||
> !(info = resident_data_ex(attr, SIZEOF_ATTRIBUTE_VOLUME_INFO))) {
[1]: https://github.com/ClangBuiltLinux/linux/issues/1729
Cheers,
Nathan