Chen Guanqiao <chen.chencha...@foxmail.com> writes:

> +static int fat_check_volume_label(const char *label)
> +{
> +     int i;
> +
> +     for (i=0; i<11; ++i) {
> +             switch (label[i]) {
> +             case 0x20:
> +             case 'A' ... 'Z':
> +             case '0' ... '9':
> +                     continue;
> +             case 0:
> +                     return 0;
> +             default:
> +                     return -EINVAL;
> +             }
> +     }
> +     return -EINVAL;
> +}

This check is really work? Especially what Windows show if '\0' is
included in label?

> +static int fat_ioctl_get_volume_label(struct inode *inode,
> +                                   u8 __user *vol_label)
> +{
> +     int ret = 0;
> +     struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
> +
> +     if (copy_to_user(vol_label, sbi->vol_label, sizeof(sbi->vol_label)))
> +             ret = -EFAULT;
> +
> +     return ret;
> +}

This should handle the label in root dir too.

> +     inode_lock(inode);

Lock is not enough.

> +     if (sb_rdonly(inode->i_sb)) {
> +             err = -EROFS;
> +             goto out_unlock_inode;
> +     }

mnt_want_write_file() checks it already.

> +     /* handling sector's vol_label */
> +     bh = sb_bread(inode->i_sb, 0);
> +     if (bh == NULL) {
> +             fat_msg(inode->i_sb, KERN_ERR,
> +                     "unable to read boot sector to write volume label");
> +             err = -EFAULT;

-EIO

> +     if (b->fat16.signature == 0x28 || b->fat32.signature == 0x28) {
> +             fat_msg(inode->i_sb, KERN_ERR,
> +                     "volume label supported since OS/2 1.2 and MS-DOS 4.0 "
> +                     "and higher");
> +             err = -EFAULT;
> +             goto out_unlock_inode;
> +     }

I don't know though, is this check necessary?

> +     /* handling root directory's vol_label */
> +     bh = sb_bread(sb, sbi->dir_start);
> +     entry = &((struct msdos_dir_entry *)(bh->b_data))[0];
> +
> +     lock_buffer(bh);
> +     memcpy(entry->name, label, sizeof(entry->name));
> +     mark_buffer_dirty(bh);
> +     unlock_buffer(bh);
> +     brelse(bh);

This totally doesn't work. Please check other implementations how to
handle label.

> + out_unlock_inode:
> +     inode_unlock(inode);

Missing release mnt_want_write_file().

Thanks.

Reply via email to