ChenGuanqiao <chen.chencha...@foxmail.com> writes:

> +static int fat_check_d_characters(char *label, unsigned long len)
> +{
> +     int i;
> +
> +     for (i = 0; i < len; ++i) {
> +             switch (label[i]) {
> +             case 'a' ... 'z':
> +                     label[i] = __toupper(label[i]);
> +             case 'A' ... 'Z':
> +             case '0' ... '9':
> +             case '_':
> +             case 0x20:
> +                     continue;
> +             default:
> +                     return -EINVAL;
> +             }

Same question with previous though, what windows do if label = "a b c"?
(this is including space other than end of name or extension.)

> +     }
> +
> +     return 0;
> +}

> +static int fat_ioctl_set_volume_label(struct file *file,
> +                                   u8 __user *vol_label)
> +{
> +     int err = 0;
> +     u8 label[MSDOS_NAME];
> +     struct timespec ts;
> +     struct buffer_head *boot_bh;
> +     struct buffer_head *vol_bh;
> +     struct msdos_dir_entry *de;
> +     struct fat_boot_sector *b;
> +     struct inode *inode = file_inode(file);
> +     struct super_block *sb = inode->i_sb;
> +     struct msdos_sb_info *sbi = MSDOS_SB(sb);
> +

[...]

> +     err = mnt_want_write_file(file);
> +     if (err)
> +             goto out;
> +
> +     down_write(&sb->s_umount);

Looks like inode_lock() for rootdir is gone. It is necessary to
traverse+modify.

> +     /* Updates root directory's vol_label */
> +     err = fat_get_volume_label_entry(inode, &vol_bh, &de);
> +     ts = current_time(inode);
> +     if (err) {
> +             /* Create volume label entry */
> +             err = fat_add_volume_label_entry(inode, label, &ts);
> +             if (err)
> +                     goto out_vol_brelse;
> +     } else {
> +             /* Write to root directory */
> +             memcpy(de->name, label, sizeof(de->name));
> +             inode->i_ctime = inode->i_mtime = inode->i_atime = ts;
> +
> +             mark_buffer_dirty(vol_bh);
> +     }
> +
> +     /* Update sector's vol_label */
> +     boot_bh = sb_bread(sb, 0);
> +     if (boot_bh == NULL) {
> +             fat_msg(sb, KERN_ERR,
> +                     "unable to read boot sector to write volume label");
> +             err = -EIO;
> +             goto out_boot_brelse;
> +     }
> +
> +     b = (struct fat_boot_sector *)boot_bh->b_data;
> +     if (sbi->fat_bits == 32)
> +             memcpy(b->fat32.vol_label, label, sizeof(label));
> +     else
> +             memcpy(b->fat16.vol_label, label, sizeof(label));
> +
> +     mark_buffer_dirty(boot_bh);
> +
> +     /* Synchronize the data together */
> +     err = sync_dirty_buffer(boot_bh);
> +     if (err)
> +             goto out_boot_brelse;
-- 
OGAWA Hirofumi <hirof...@mail.parknet.co.jp>

Reply via email to