| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * linux/fs/fat/dir.c |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 57 | 58 | if ((iblock & (sbi->sec_per_clus - 1)) || sbi->sec_per_clus == 1) |
|---|
| 58 | 59 | return; |
|---|
| 59 | 60 | /* root dir of FAT12/FAT16 */ |
|---|
| 60 | | - if ((sbi->fat_bits != 32) && (dir->i_ino == MSDOS_ROOT_INO)) |
|---|
| 61 | + if (!is_fat32(sbi) && (dir->i_ino == MSDOS_ROOT_INO)) |
|---|
| 61 | 62 | return; |
|---|
| 62 | 63 | |
|---|
| 63 | 64 | bh = sb_find_get_block(sb, phys); |
|---|
| .. | .. |
|---|
| 87 | 88 | int err, offset; |
|---|
| 88 | 89 | |
|---|
| 89 | 90 | next: |
|---|
| 90 | | - if (*bh) |
|---|
| 91 | | - brelse(*bh); |
|---|
| 92 | | - |
|---|
| 91 | + brelse(*bh); |
|---|
| 93 | 92 | *bh = NULL; |
|---|
| 94 | 93 | iblock = *pos >> sb->s_blocksize_bits; |
|---|
| 95 | 94 | err = fat_bmap(dir, iblock, &phys, &mapped_blocks, 0, false); |
|---|
| .. | .. |
|---|
| 369 | 368 | } |
|---|
| 370 | 369 | |
|---|
| 371 | 370 | memcpy(work, de->name, sizeof(work)); |
|---|
| 372 | | - /* see namei.c, msdos_format_name */ |
|---|
| 371 | + /* For an explanation of the special treatment of 0x05 in |
|---|
| 372 | + * filenames, see msdos_format_name in namei_msdos.c |
|---|
| 373 | + */ |
|---|
| 373 | 374 | if (work[0] == 0x05) |
|---|
| 374 | 375 | work[0] = 0xE5; |
|---|
| 375 | 376 | |
|---|
| .. | .. |
|---|
| 803 | 804 | return fat_generic_ioctl(filp, cmd, arg); |
|---|
| 804 | 805 | } |
|---|
| 805 | 806 | |
|---|
| 806 | | - if (!access_ok(VERIFY_WRITE, d1, sizeof(struct __fat_dirent[2]))) |
|---|
| 807 | | - return -EFAULT; |
|---|
| 808 | 807 | /* |
|---|
| 809 | 808 | * Yes, we don't need this put_user() absolutely. However old |
|---|
| 810 | 809 | * code didn't return the right value. So, app use this value, |
|---|
| .. | .. |
|---|
| 843 | 842 | return fat_generic_ioctl(filp, cmd, (unsigned long)arg); |
|---|
| 844 | 843 | } |
|---|
| 845 | 844 | |
|---|
| 846 | | - if (!access_ok(VERIFY_WRITE, d1, sizeof(struct compat_dirent[2]))) |
|---|
| 847 | | - return -EFAULT; |
|---|
| 848 | 845 | /* |
|---|
| 849 | 846 | * Yes, we don't need this put_user() absolutely. However old |
|---|
| 850 | 847 | * code didn't return the right value. So, app use this value, |
|---|
| .. | .. |
|---|
| 1071 | 1068 | } |
|---|
| 1072 | 1069 | } |
|---|
| 1073 | 1070 | |
|---|
| 1074 | | - dir->i_mtime = dir->i_atime = current_time(dir); |
|---|
| 1071 | + fat_truncate_time(dir, NULL, S_ATIME|S_MTIME); |
|---|
| 1075 | 1072 | if (IS_DIRSYNC(dir)) |
|---|
| 1076 | 1073 | (void)fat_sync_inode(dir); |
|---|
| 1077 | 1074 | else |
|---|
| .. | .. |
|---|
| 1287 | 1284 | struct super_block *sb = dir->i_sb; |
|---|
| 1288 | 1285 | struct msdos_sb_info *sbi = MSDOS_SB(sb); |
|---|
| 1289 | 1286 | struct buffer_head *bh, *prev, *bhs[3]; /* 32*slots (672bytes) */ |
|---|
| 1290 | | - struct msdos_dir_entry *uninitialized_var(de); |
|---|
| 1287 | + struct msdos_dir_entry *de; |
|---|
| 1291 | 1288 | int err, free_slots, i, nr_bhs; |
|---|
| 1292 | 1289 | loff_t pos, i_pos; |
|---|
| 1293 | 1290 | |
|---|
| .. | .. |
|---|
| 1320 | 1317 | } |
|---|
| 1321 | 1318 | } |
|---|
| 1322 | 1319 | if (dir->i_ino == MSDOS_ROOT_INO) { |
|---|
| 1323 | | - if (sbi->fat_bits != 32) |
|---|
| 1320 | + if (!is_fat32(sbi)) |
|---|
| 1324 | 1321 | goto error; |
|---|
| 1325 | 1322 | } else if (MSDOS_I(dir)->i_start == 0) { |
|---|
| 1326 | 1323 | fat_msg(sb, KERN_ERR, "Corrupted directory (i_pos %lld)", |
|---|