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.c55
1 files changed, 40 insertions, 15 deletions
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index 5bafaad00530..35806813ea4e 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -26,6 +26,7 @@
26#include <linux/writeback.h> 26#include <linux/writeback.h>
27#include <linux/log2.h> 27#include <linux/log2.h>
28#include <linux/hash.h> 28#include <linux/hash.h>
29#include <linux/blkdev.h>
29#include <asm/unaligned.h> 30#include <asm/unaligned.h>
30#include "fat.h" 31#include "fat.h"
31 32
@@ -725,7 +726,8 @@ static int fat_show_options(struct seq_file *m, struct dentry *root)
725 if (opts->allow_utime) 726 if (opts->allow_utime)
726 seq_printf(m, ",allow_utime=%04o", opts->allow_utime); 727 seq_printf(m, ",allow_utime=%04o", opts->allow_utime);
727 if (sbi->nls_disk) 728 if (sbi->nls_disk)
728 seq_printf(m, ",codepage=%s", sbi->nls_disk->charset); 729 /* strip "cp" prefix from displayed option */
730 seq_printf(m, ",codepage=%s", &sbi->nls_disk->charset[2]);
729 if (isvfat) { 731 if (isvfat) {
730 if (sbi->nls_io) 732 if (sbi->nls_io)
731 seq_printf(m, ",iocharset=%s", sbi->nls_io->charset); 733 seq_printf(m, ",iocharset=%s", sbi->nls_io->charset);
@@ -777,8 +779,12 @@ static int fat_show_options(struct seq_file *m, struct dentry *root)
777 } 779 }
778 if (opts->flush) 780 if (opts->flush)
779 seq_puts(m, ",flush"); 781 seq_puts(m, ",flush");
780 if (opts->tz_utc) 782 if (opts->tz_set) {
781 seq_puts(m, ",tz=UTC"); 783 if (opts->time_offset)
784 seq_printf(m, ",time_offset=%d", opts->time_offset);
785 else
786 seq_puts(m, ",tz=UTC");
787 }
782 if (opts->errors == FAT_ERRORS_CONT) 788 if (opts->errors == FAT_ERRORS_CONT)
783 seq_puts(m, ",errors=continue"); 789 seq_puts(m, ",errors=continue");
784 else if (opts->errors == FAT_ERRORS_PANIC) 790 else if (opts->errors == FAT_ERRORS_PANIC)
@@ -800,7 +806,8 @@ enum {
800 Opt_shortname_winnt, Opt_shortname_mixed, Opt_utf8_no, Opt_utf8_yes, 806 Opt_shortname_winnt, Opt_shortname_mixed, Opt_utf8_no, Opt_utf8_yes,
801 Opt_uni_xl_no, Opt_uni_xl_yes, Opt_nonumtail_no, Opt_nonumtail_yes, 807 Opt_uni_xl_no, Opt_uni_xl_yes, Opt_nonumtail_no, Opt_nonumtail_yes,
802 Opt_obsolete, Opt_flush, Opt_tz_utc, Opt_rodir, Opt_err_cont, 808 Opt_obsolete, Opt_flush, Opt_tz_utc, Opt_rodir, Opt_err_cont,
803 Opt_err_panic, Opt_err_ro, Opt_discard, Opt_nfs, Opt_err, 809 Opt_err_panic, Opt_err_ro, Opt_discard, Opt_nfs, Opt_time_offset,
810 Opt_err,
804}; 811};
805 812
806static const match_table_t fat_tokens = { 813static const match_table_t fat_tokens = {
@@ -825,6 +832,7 @@ static const match_table_t fat_tokens = {
825 {Opt_immutable, "sys_immutable"}, 832 {Opt_immutable, "sys_immutable"},
826 {Opt_flush, "flush"}, 833 {Opt_flush, "flush"},
827 {Opt_tz_utc, "tz=UTC"}, 834 {Opt_tz_utc, "tz=UTC"},
835 {Opt_time_offset, "time_offset=%d"},
828 {Opt_err_cont, "errors=continue"}, 836 {Opt_err_cont, "errors=continue"},
829 {Opt_err_panic, "errors=panic"}, 837 {Opt_err_panic, "errors=panic"},
830 {Opt_err_ro, "errors=remount-ro"}, 838 {Opt_err_ro, "errors=remount-ro"},
@@ -909,7 +917,7 @@ static int parse_options(struct super_block *sb, char *options, int is_vfat,
909 opts->utf8 = opts->unicode_xlate = 0; 917 opts->utf8 = opts->unicode_xlate = 0;
910 opts->numtail = 1; 918 opts->numtail = 1;
911 opts->usefree = opts->nocase = 0; 919 opts->usefree = opts->nocase = 0;
912 opts->tz_utc = 0; 920 opts->tz_set = 0;
913 opts->nfs = 0; 921 opts->nfs = 0;
914 opts->errors = FAT_ERRORS_RO; 922 opts->errors = FAT_ERRORS_RO;
915 *debug = 0; 923 *debug = 0;
@@ -965,48 +973,57 @@ static int parse_options(struct super_block *sb, char *options, int is_vfat,
965 break; 973 break;
966 case Opt_uid: 974 case Opt_uid:
967 if (match_int(&args[0], &option)) 975 if (match_int(&args[0], &option))
968 return 0; 976 return -EINVAL;
969 opts->fs_uid = make_kuid(current_user_ns(), option); 977 opts->fs_uid = make_kuid(current_user_ns(), option);
970 if (!uid_valid(opts->fs_uid)) 978 if (!uid_valid(opts->fs_uid))
971 return 0; 979 return -EINVAL;
972 break; 980 break;
973 case Opt_gid: 981 case Opt_gid:
974 if (match_int(&args[0], &option)) 982 if (match_int(&args[0], &option))
975 return 0; 983 return -EINVAL;
976 opts->fs_gid = make_kgid(current_user_ns(), option); 984 opts->fs_gid = make_kgid(current_user_ns(), option);
977 if (!gid_valid(opts->fs_gid)) 985 if (!gid_valid(opts->fs_gid))
978 return 0; 986 return -EINVAL;
979 break; 987 break;
980 case Opt_umask: 988 case Opt_umask:
981 if (match_octal(&args[0], &option)) 989 if (match_octal(&args[0], &option))
982 return 0; 990 return -EINVAL;
983 opts->fs_fmask = opts->fs_dmask = option; 991 opts->fs_fmask = opts->fs_dmask = option;
984 break; 992 break;
985 case Opt_dmask: 993 case Opt_dmask:
986 if (match_octal(&args[0], &option)) 994 if (match_octal(&args[0], &option))
987 return 0; 995 return -EINVAL;
988 opts->fs_dmask = option; 996 opts->fs_dmask = option;
989 break; 997 break;
990 case Opt_fmask: 998 case Opt_fmask:
991 if (match_octal(&args[0], &option)) 999 if (match_octal(&args[0], &option))
992 return 0; 1000 return -EINVAL;
993 opts->fs_fmask = option; 1001 opts->fs_fmask = option;
994 break; 1002 break;
995 case Opt_allow_utime: 1003 case Opt_allow_utime:
996 if (match_octal(&args[0], &option)) 1004 if (match_octal(&args[0], &option))
997 return 0; 1005 return -EINVAL;
998 opts->allow_utime = option & (S_IWGRP | S_IWOTH); 1006 opts->allow_utime = option & (S_IWGRP | S_IWOTH);
999 break; 1007 break;
1000 case Opt_codepage: 1008 case Opt_codepage:
1001 if (match_int(&args[0], &option)) 1009 if (match_int(&args[0], &option))
1002 return 0; 1010 return -EINVAL;
1003 opts->codepage = option; 1011 opts->codepage = option;
1004 break; 1012 break;
1005 case Opt_flush: 1013 case Opt_flush:
1006 opts->flush = 1; 1014 opts->flush = 1;
1007 break; 1015 break;
1016 case Opt_time_offset:
1017 if (match_int(&args[0], &option))
1018 return -EINVAL;
1019 if (option < -12 * 60 || option > 12 * 60)
1020 return -EINVAL;
1021 opts->tz_set = 1;
1022 opts->time_offset = option;
1023 break;
1008 case Opt_tz_utc: 1024 case Opt_tz_utc:
1009 opts->tz_utc = 1; 1025 opts->tz_set = 1;
1026 opts->time_offset = 0;
1010 break; 1027 break;
1011 case Opt_err_cont: 1028 case Opt_err_cont:
1012 opts->errors = FAT_ERRORS_CONT; 1029 opts->errors = FAT_ERRORS_CONT;
@@ -1431,6 +1448,14 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat,
1431 goto out_fail; 1448 goto out_fail;
1432 } 1449 }
1433 1450
1451 if (sbi->options.discard) {
1452 struct request_queue *q = bdev_get_queue(sb->s_bdev);
1453 if (!blk_queue_discard(q))
1454 fat_msg(sb, KERN_WARNING,
1455 "mounting with \"discard\" option, but "
1456 "the device does not support discard");
1457 }
1458
1434 return 0; 1459 return 0;
1435 1460
1436out_invalid: 1461out_invalid: