aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fat/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/fat/inode.c')
-rw-r--r--fs/fat/inode.c38
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);
433static void fat_delete_inode(struct inode *inode) 433static 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
846enum { 843enum {
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