aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fat
diff options
context:
space:
mode:
authorNamjae Jeon <namjae.jeon@samsung.com>2013-04-29 19:21:08 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-04-29 21:28:40 -0400
commit2628b7a6ac0d7d8246b6781a3e4489d78391ab54 (patch)
tree9befb3e857086352412a785ec779f4ea74bb845d /fs/fat
parent35623715818dfa720cccf99cd280dcbb4b78da23 (diff)
fat: introduce 2 new values for the -o nfs mount option
This patchset eliminates the client side ESTALE errors when a FAT partition exported over NFS has its dentries evicted from the cache. The idea is to find the on-disk location_'i_pos' of the dirent of the inode that has been evicted and use it to rebuild the inode. This patch: Provide two possible values 'stale_rw' and 'nostale_ro' for the -o nfs mount option.The first one allows all file operations but does not reduce ESTALE errors on memory constrained systems. The second one eliminates ESTALE errors but mounts the filesystem as read-only. Not specifying a value defaults to 'stale_rw'. Signed-off-by: Namjae Jeon <namjae.jeon@samsung.com> Signed-off-by: Ravishankar N <ravi.n1@samsung.com> Signed-off-by: Amit Sahrawat <a.sahrawat@samsung.com> Acked-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/fat')
-rw-r--r--fs/fat/fat.h7
-rw-r--r--fs/fat/inode.c23
2 files changed, 21 insertions, 9 deletions
diff --git a/fs/fat/fat.h b/fs/fat/fat.h
index e9cc3f0d58e2..a7b1d86b37c7 100644
--- a/fs/fat/fat.h
+++ b/fs/fat/fat.h
@@ -23,6 +23,9 @@
23#define FAT_ERRORS_PANIC 2 /* panic on error */ 23#define FAT_ERRORS_PANIC 2 /* panic on error */
24#define FAT_ERRORS_RO 3 /* remount r/o on error */ 24#define FAT_ERRORS_RO 3 /* remount r/o on error */
25 25
26#define FAT_NFS_STALE_RW 1 /* NFS RW support, can cause ESTALE */
27#define FAT_NFS_NOSTALE_RO 2 /* NFS RO support, no ESTALE issue */
28
26struct fat_mount_options { 29struct fat_mount_options {
27 kuid_t fs_uid; 30 kuid_t fs_uid;
28 kgid_t fs_gid; 31 kgid_t fs_gid;
@@ -34,6 +37,7 @@ struct fat_mount_options {
34 unsigned short shortname; /* flags for shortname display/create rule */ 37 unsigned short shortname; /* flags for shortname display/create rule */
35 unsigned char name_check; /* r = relaxed, n = normal, s = strict */ 38 unsigned char name_check; /* r = relaxed, n = normal, s = strict */
36 unsigned char errors; /* On error: continue, panic, remount-ro */ 39 unsigned char errors; /* On error: continue, panic, remount-ro */
40 unsigned char nfs; /* NFS support: nostale_ro, stale_rw */
37 unsigned short allow_utime;/* permission for setting the [am]time */ 41 unsigned short allow_utime;/* permission for setting the [am]time */
38 unsigned quiet:1, /* set = fake successful chmods and chowns */ 42 unsigned quiet:1, /* set = fake successful chmods and chowns */
39 showexec:1, /* set = only set x bit for com/exe/bat */ 43 showexec:1, /* set = only set x bit for com/exe/bat */
@@ -48,8 +52,7 @@ struct fat_mount_options {
48 usefree:1, /* Use free_clusters for FAT32 */ 52 usefree:1, /* Use free_clusters for FAT32 */
49 tz_set:1, /* Filesystem timestamps' offset set */ 53 tz_set:1, /* Filesystem timestamps' offset set */
50 rodir:1, /* allow ATTR_RO for directory */ 54 rodir:1, /* allow ATTR_RO for directory */
51 discard:1, /* Issue discard requests on deletions */ 55 discard:1; /* Issue discard requests on deletions */
52 nfs:1; /* Do extra work needed for NFS export */
53}; 56};
54 57
55#define FAT_HASH_BITS 8 58#define FAT_HASH_BITS 8
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index acf6e479b443..93fbc8a7f098 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -814,8 +814,6 @@ static int fat_show_options(struct seq_file *m, struct dentry *root)
814 seq_puts(m, ",usefree"); 814 seq_puts(m, ",usefree");
815 if (opts->quiet) 815 if (opts->quiet)
816 seq_puts(m, ",quiet"); 816 seq_puts(m, ",quiet");
817 if (opts->nfs)
818 seq_puts(m, ",nfs");
819 if (opts->showexec) 817 if (opts->showexec)
820 seq_puts(m, ",showexec"); 818 seq_puts(m, ",showexec");
821 if (opts->sys_immutable) 819 if (opts->sys_immutable)
@@ -849,6 +847,10 @@ static int fat_show_options(struct seq_file *m, struct dentry *root)
849 seq_puts(m, ",errors=panic"); 847 seq_puts(m, ",errors=panic");
850 else 848 else
851 seq_puts(m, ",errors=remount-ro"); 849 seq_puts(m, ",errors=remount-ro");
850 if (opts->nfs == FAT_NFS_NOSTALE_RO)
851 seq_puts(m, ",nfs=nostale_ro");
852 else if (opts->nfs)
853 seq_puts(m, ",nfs=stale_rw");
852 if (opts->discard) 854 if (opts->discard)
853 seq_puts(m, ",discard"); 855 seq_puts(m, ",discard");
854 856
@@ -865,7 +867,7 @@ enum {
865 Opt_uni_xl_no, Opt_uni_xl_yes, Opt_nonumtail_no, Opt_nonumtail_yes, 867 Opt_uni_xl_no, Opt_uni_xl_yes, Opt_nonumtail_no, Opt_nonumtail_yes,
866 Opt_obsolete, Opt_flush, Opt_tz_utc, Opt_rodir, Opt_err_cont, 868 Opt_obsolete, Opt_flush, Opt_tz_utc, Opt_rodir, Opt_err_cont,
867 Opt_err_panic, Opt_err_ro, Opt_discard, Opt_nfs, Opt_time_offset, 869 Opt_err_panic, Opt_err_ro, Opt_discard, Opt_nfs, Opt_time_offset,
868 Opt_err, 870 Opt_nfs_stale_rw, Opt_nfs_nostale_ro, Opt_err,
869}; 871};
870 872
871static const match_table_t fat_tokens = { 873static const match_table_t fat_tokens = {
@@ -895,7 +897,9 @@ static const match_table_t fat_tokens = {
895 {Opt_err_panic, "errors=panic"}, 897 {Opt_err_panic, "errors=panic"},
896 {Opt_err_ro, "errors=remount-ro"}, 898 {Opt_err_ro, "errors=remount-ro"},
897 {Opt_discard, "discard"}, 899 {Opt_discard, "discard"},
898 {Opt_nfs, "nfs"}, 900 {Opt_nfs_stale_rw, "nfs"},
901 {Opt_nfs_stale_rw, "nfs=stale_rw"},
902 {Opt_nfs_nostale_ro, "nfs=nostale_ro"},
899 {Opt_obsolete, "conv=binary"}, 903 {Opt_obsolete, "conv=binary"},
900 {Opt_obsolete, "conv=text"}, 904 {Opt_obsolete, "conv=text"},
901 {Opt_obsolete, "conv=auto"}, 905 {Opt_obsolete, "conv=auto"},
@@ -1092,6 +1096,12 @@ static int parse_options(struct super_block *sb, char *options, int is_vfat,
1092 case Opt_err_ro: 1096 case Opt_err_ro:
1093 opts->errors = FAT_ERRORS_RO; 1097 opts->errors = FAT_ERRORS_RO;
1094 break; 1098 break;
1099 case Opt_nfs_stale_rw:
1100 opts->nfs = FAT_NFS_STALE_RW;
1101 break;
1102 case Opt_nfs_nostale_ro:
1103 opts->nfs = FAT_NFS_NOSTALE_RO;
1104 break;
1095 1105
1096 /* msdos specific */ 1106 /* msdos specific */
1097 case Opt_dots: 1107 case Opt_dots:
@@ -1150,9 +1160,6 @@ static int parse_options(struct super_block *sb, char *options, int is_vfat,
1150 case Opt_discard: 1160 case Opt_discard:
1151 opts->discard = 1; 1161 opts->discard = 1;
1152 break; 1162 break;
1153 case Opt_nfs:
1154 opts->nfs = 1;
1155 break;
1156 1163
1157 /* obsolete mount options */ 1164 /* obsolete mount options */
1158 case Opt_obsolete: 1165 case Opt_obsolete:
@@ -1183,6 +1190,8 @@ out:
1183 opts->allow_utime = ~opts->fs_dmask & (S_IWGRP | S_IWOTH); 1190 opts->allow_utime = ~opts->fs_dmask & (S_IWGRP | S_IWOTH);
1184 if (opts->unicode_xlate) 1191 if (opts->unicode_xlate)
1185 opts->utf8 = 0; 1192 opts->utf8 = 0;
1193 if (opts->nfs == FAT_NFS_NOSTALE_RO)
1194 sb->s_flags |= MS_RDONLY;
1186 1195
1187 return 0; 1196 return 0;
1188} 1197}