diff options
Diffstat (limited to 'fs/fat/inode.c')
-rw-r--r-- | fs/fat/inode.c | 38 |
1 files changed, 23 insertions, 15 deletions
diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 53f3cf62b7c1..5f522a55b596 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c | |||
@@ -433,11 +433,8 @@ EXPORT_SYMBOL_GPL(fat_build_inode); | |||
433 | static void fat_delete_inode(struct inode *inode) | 433 | static void fat_delete_inode(struct inode *inode) |
434 | { | 434 | { |
435 | truncate_inode_pages(&inode->i_data, 0); | 435 | truncate_inode_pages(&inode->i_data, 0); |
436 | 436 | inode->i_size = 0; | |
437 | if (!is_bad_inode(inode)) { | 437 | fat_truncate(inode); |
438 | inode->i_size = 0; | ||
439 | fat_truncate(inode); | ||
440 | } | ||
441 | clear_inode(inode); | 438 | clear_inode(inode); |
442 | } | 439 | } |
443 | 440 | ||
@@ -445,8 +442,6 @@ static void fat_clear_inode(struct inode *inode) | |||
445 | { | 442 | { |
446 | struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb); | 443 | struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb); |
447 | 444 | ||
448 | if (is_bad_inode(inode)) | ||
449 | return; | ||
450 | lock_kernel(); | 445 | lock_kernel(); |
451 | spin_lock(&sbi->inode_hash_lock); | 446 | spin_lock(&sbi->inode_hash_lock); |
452 | fat_cache_inval_inode(inode); | 447 | fat_cache_inval_inode(inode); |
@@ -542,7 +537,7 @@ static int fat_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
542 | struct msdos_sb_info *sbi = MSDOS_SB(dentry->d_sb); | 537 | struct msdos_sb_info *sbi = MSDOS_SB(dentry->d_sb); |
543 | 538 | ||
544 | /* If the count of free cluster is still unknown, counts it here. */ | 539 | /* If the count of free cluster is still unknown, counts it here. */ |
545 | if (sbi->free_clusters == -1) { | 540 | if (sbi->free_clusters == -1 || !sbi->free_clus_valid) { |
546 | int err = fat_count_free_clusters(dentry->d_sb); | 541 | int err = fat_count_free_clusters(dentry->d_sb); |
547 | if (err) | 542 | if (err) |
548 | return err; | 543 | return err; |
@@ -790,6 +785,8 @@ static int fat_show_options(struct seq_file *m, struct vfsmount *mnt) | |||
790 | seq_printf(m, ",gid=%u", opts->fs_gid); | 785 | seq_printf(m, ",gid=%u", opts->fs_gid); |
791 | seq_printf(m, ",fmask=%04o", opts->fs_fmask); | 786 | seq_printf(m, ",fmask=%04o", opts->fs_fmask); |
792 | seq_printf(m, ",dmask=%04o", opts->fs_dmask); | 787 | seq_printf(m, ",dmask=%04o", opts->fs_dmask); |
788 | if (opts->allow_utime) | ||
789 | seq_printf(m, ",allow_utime=%04o", opts->allow_utime); | ||
793 | if (sbi->nls_disk) | 790 | if (sbi->nls_disk) |
794 | seq_printf(m, ",codepage=%s", sbi->nls_disk->charset); | 791 | seq_printf(m, ",codepage=%s", sbi->nls_disk->charset); |
795 | if (isvfat) { | 792 | if (isvfat) { |
@@ -845,9 +842,9 @@ static int fat_show_options(struct seq_file *m, struct vfsmount *mnt) | |||
845 | 842 | ||
846 | enum { | 843 | enum { |
847 | Opt_check_n, Opt_check_r, Opt_check_s, Opt_uid, Opt_gid, | 844 | Opt_check_n, Opt_check_r, Opt_check_s, Opt_uid, Opt_gid, |
848 | Opt_umask, Opt_dmask, Opt_fmask, Opt_codepage, Opt_usefree, Opt_nocase, | 845 | Opt_umask, Opt_dmask, Opt_fmask, Opt_allow_utime, Opt_codepage, |
849 | Opt_quiet, Opt_showexec, Opt_debug, Opt_immutable, | 846 | Opt_usefree, Opt_nocase, Opt_quiet, Opt_showexec, Opt_debug, |
850 | Opt_dots, Opt_nodots, | 847 | Opt_immutable, Opt_dots, Opt_nodots, |
851 | Opt_charset, Opt_shortname_lower, Opt_shortname_win95, | 848 | Opt_charset, Opt_shortname_lower, Opt_shortname_win95, |
852 | Opt_shortname_winnt, Opt_shortname_mixed, Opt_utf8_no, Opt_utf8_yes, | 849 | Opt_shortname_winnt, Opt_shortname_mixed, Opt_utf8_no, Opt_utf8_yes, |
853 | Opt_uni_xl_no, Opt_uni_xl_yes, Opt_nonumtail_no, Opt_nonumtail_yes, | 850 | Opt_uni_xl_no, Opt_uni_xl_yes, Opt_nonumtail_no, Opt_nonumtail_yes, |
@@ -866,6 +863,7 @@ static match_table_t fat_tokens = { | |||
866 | {Opt_umask, "umask=%o"}, | 863 | {Opt_umask, "umask=%o"}, |
867 | {Opt_dmask, "dmask=%o"}, | 864 | {Opt_dmask, "dmask=%o"}, |
868 | {Opt_fmask, "fmask=%o"}, | 865 | {Opt_fmask, "fmask=%o"}, |
866 | {Opt_allow_utime, "allow_utime=%o"}, | ||
869 | {Opt_codepage, "codepage=%u"}, | 867 | {Opt_codepage, "codepage=%u"}, |
870 | {Opt_usefree, "usefree"}, | 868 | {Opt_usefree, "usefree"}, |
871 | {Opt_nocase, "nocase"}, | 869 | {Opt_nocase, "nocase"}, |
@@ -937,6 +935,7 @@ static int parse_options(char *options, int is_vfat, int silent, int *debug, | |||
937 | opts->fs_uid = current->uid; | 935 | opts->fs_uid = current->uid; |
938 | opts->fs_gid = current->gid; | 936 | opts->fs_gid = current->gid; |
939 | opts->fs_fmask = opts->fs_dmask = current->fs->umask; | 937 | opts->fs_fmask = opts->fs_dmask = current->fs->umask; |
938 | opts->allow_utime = -1; | ||
940 | opts->codepage = fat_default_codepage; | 939 | opts->codepage = fat_default_codepage; |
941 | opts->iocharset = fat_default_iocharset; | 940 | opts->iocharset = fat_default_iocharset; |
942 | if (is_vfat) | 941 | if (is_vfat) |
@@ -1024,6 +1023,11 @@ static int parse_options(char *options, int is_vfat, int silent, int *debug, | |||
1024 | return 0; | 1023 | return 0; |
1025 | opts->fs_fmask = option; | 1024 | opts->fs_fmask = option; |
1026 | break; | 1025 | break; |
1026 | case Opt_allow_utime: | ||
1027 | if (match_octal(&args[0], &option)) | ||
1028 | return 0; | ||
1029 | opts->allow_utime = option & (S_IWGRP | S_IWOTH); | ||
1030 | break; | ||
1027 | case Opt_codepage: | 1031 | case Opt_codepage: |
1028 | if (match_int(&args[0], &option)) | 1032 | if (match_int(&args[0], &option)) |
1029 | return 0; | 1033 | return 0; |
@@ -1106,6 +1110,9 @@ static int parse_options(char *options, int is_vfat, int silent, int *debug, | |||
1106 | " for FAT filesystems, filesystem will be case sensitive!\n"); | 1110 | " for FAT filesystems, filesystem will be case sensitive!\n"); |
1107 | } | 1111 | } |
1108 | 1112 | ||
1113 | /* If user doesn't specify allow_utime, it's initialized from dmask. */ | ||
1114 | if (opts->allow_utime == (unsigned short)-1) | ||
1115 | opts->allow_utime = ~opts->fs_dmask & (S_IWGRP | S_IWOTH); | ||
1109 | if (opts->unicode_xlate) | 1116 | if (opts->unicode_xlate) |
1110 | opts->utf8 = 0; | 1117 | opts->utf8 = 0; |
1111 | 1118 | ||
@@ -1208,7 +1215,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, | |||
1208 | */ | 1215 | */ |
1209 | 1216 | ||
1210 | media = b->media; | 1217 | media = b->media; |
1211 | if (!FAT_VALID_MEDIA(media)) { | 1218 | if (!fat_valid_media(media)) { |
1212 | if (!silent) | 1219 | if (!silent) |
1213 | printk(KERN_ERR "FAT: invalid media value (0x%02x)\n", | 1220 | printk(KERN_ERR "FAT: invalid media value (0x%02x)\n", |
1214 | media); | 1221 | media); |
@@ -1219,7 +1226,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, | |||
1219 | le16_to_cpu(get_unaligned((__le16 *)&b->sector_size)); | 1226 | le16_to_cpu(get_unaligned((__le16 *)&b->sector_size)); |
1220 | if (!is_power_of_2(logical_sector_size) | 1227 | if (!is_power_of_2(logical_sector_size) |
1221 | || (logical_sector_size < 512) | 1228 | || (logical_sector_size < 512) |
1222 | || (PAGE_CACHE_SIZE < logical_sector_size)) { | 1229 | || (logical_sector_size > 4096)) { |
1223 | if (!silent) | 1230 | if (!silent) |
1224 | printk(KERN_ERR "FAT: bogus logical sector size %u\n", | 1231 | printk(KERN_ERR "FAT: bogus logical sector size %u\n", |
1225 | logical_sector_size); | 1232 | logical_sector_size); |
@@ -1267,6 +1274,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, | |||
1267 | sbi->fat_length = le16_to_cpu(b->fat_length); | 1274 | sbi->fat_length = le16_to_cpu(b->fat_length); |
1268 | sbi->root_cluster = 0; | 1275 | sbi->root_cluster = 0; |
1269 | sbi->free_clusters = -1; /* Don't know yet */ | 1276 | sbi->free_clusters = -1; /* Don't know yet */ |
1277 | sbi->free_clus_valid = 0; | ||
1270 | sbi->prev_free = FAT_START_ENT; | 1278 | sbi->prev_free = FAT_START_ENT; |
1271 | 1279 | ||
1272 | if (!sbi->fat_length && b->fat32_length) { | 1280 | if (!sbi->fat_length && b->fat32_length) { |
@@ -1302,8 +1310,8 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, | |||
1302 | sbi->fsinfo_sector); | 1310 | sbi->fsinfo_sector); |
1303 | } else { | 1311 | } else { |
1304 | if (sbi->options.usefree) | 1312 | if (sbi->options.usefree) |
1305 | sbi->free_clusters = | 1313 | sbi->free_clus_valid = 1; |
1306 | le32_to_cpu(fsinfo->free_clusters); | 1314 | sbi->free_clusters = le32_to_cpu(fsinfo->free_clusters); |
1307 | sbi->prev_free = le32_to_cpu(fsinfo->next_cluster); | 1315 | sbi->prev_free = le32_to_cpu(fsinfo->next_cluster); |
1308 | } | 1316 | } |
1309 | 1317 | ||