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.c74
1 files changed, 40 insertions, 34 deletions
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index acf6e479b443..4ff901632b26 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -18,7 +18,6 @@
18#include <linux/pagemap.h> 18#include <linux/pagemap.h>
19#include <linux/mpage.h> 19#include <linux/mpage.h>
20#include <linux/buffer_head.h> 20#include <linux/buffer_head.h>
21#include <linux/exportfs.h>
22#include <linux/mount.h> 21#include <linux/mount.h>
23#include <linux/vfs.h> 22#include <linux/vfs.h>
24#include <linux/parser.h> 23#include <linux/parser.h>
@@ -385,7 +384,7 @@ static int fat_calc_dir_size(struct inode *inode)
385} 384}
386 385
387/* doesn't deal with root inode */ 386/* doesn't deal with root inode */
388static int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de) 387int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de)
389{ 388{
390 struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb); 389 struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
391 int error; 390 int error;
@@ -444,12 +443,25 @@ static int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de)
444 return 0; 443 return 0;
445} 444}
446 445
446static inline void fat_lock_build_inode(struct msdos_sb_info *sbi)
447{
448 if (sbi->options.nfs == FAT_NFS_NOSTALE_RO)
449 mutex_lock(&sbi->nfs_build_inode_lock);
450}
451
452static inline void fat_unlock_build_inode(struct msdos_sb_info *sbi)
453{
454 if (sbi->options.nfs == FAT_NFS_NOSTALE_RO)
455 mutex_unlock(&sbi->nfs_build_inode_lock);
456}
457
447struct inode *fat_build_inode(struct super_block *sb, 458struct inode *fat_build_inode(struct super_block *sb,
448 struct msdos_dir_entry *de, loff_t i_pos) 459 struct msdos_dir_entry *de, loff_t i_pos)
449{ 460{
450 struct inode *inode; 461 struct inode *inode;
451 int err; 462 int err;
452 463
464 fat_lock_build_inode(MSDOS_SB(sb));
453 inode = fat_iget(sb, i_pos); 465 inode = fat_iget(sb, i_pos);
454 if (inode) 466 if (inode)
455 goto out; 467 goto out;
@@ -469,6 +481,7 @@ struct inode *fat_build_inode(struct super_block *sb,
469 fat_attach(inode, i_pos); 481 fat_attach(inode, i_pos);
470 insert_inode_hash(inode); 482 insert_inode_hash(inode);
471out: 483out:
484 fat_unlock_build_inode(MSDOS_SB(sb));
472 return inode; 485 return inode;
473} 486}
474 487
@@ -655,20 +668,6 @@ static int fat_statfs(struct dentry *dentry, struct kstatfs *buf)
655 return 0; 668 return 0;
656} 669}
657 670
658static inline loff_t fat_i_pos_read(struct msdos_sb_info *sbi,
659 struct inode *inode)
660{
661 loff_t i_pos;
662#if BITS_PER_LONG == 32
663 spin_lock(&sbi->inode_hash_lock);
664#endif
665 i_pos = MSDOS_I(inode)->i_pos;
666#if BITS_PER_LONG == 32
667 spin_unlock(&sbi->inode_hash_lock);
668#endif
669 return i_pos;
670}
671
672static int __fat_write_inode(struct inode *inode, int wait) 671static int __fat_write_inode(struct inode *inode, int wait)
673{ 672{
674 struct super_block *sb = inode->i_sb; 673 struct super_block *sb = inode->i_sb;
@@ -676,7 +675,8 @@ static int __fat_write_inode(struct inode *inode, int wait)
676 struct buffer_head *bh; 675 struct buffer_head *bh;
677 struct msdos_dir_entry *raw_entry; 676 struct msdos_dir_entry *raw_entry;
678 loff_t i_pos; 677 loff_t i_pos;
679 int err; 678 sector_t blocknr;
679 int err, offset;
680 680
681 if (inode->i_ino == MSDOS_ROOT_INO) 681 if (inode->i_ino == MSDOS_ROOT_INO)
682 return 0; 682 return 0;
@@ -686,7 +686,8 @@ retry:
686 if (!i_pos) 686 if (!i_pos)
687 return 0; 687 return 0;
688 688
689 bh = sb_bread(sb, i_pos >> sbi->dir_per_block_bits); 689 fat_get_blknr_offset(sbi, i_pos, &blocknr, &offset);
690 bh = sb_bread(sb, blocknr);
690 if (!bh) { 691 if (!bh) {
691 fat_msg(sb, KERN_ERR, "unable to read inode block " 692 fat_msg(sb, KERN_ERR, "unable to read inode block "
692 "for updating (i_pos %lld)", i_pos); 693 "for updating (i_pos %lld)", i_pos);
@@ -699,8 +700,7 @@ retry:
699 goto retry; 700 goto retry;
700 } 701 }
701 702
702 raw_entry = &((struct msdos_dir_entry *) (bh->b_data)) 703 raw_entry = &((struct msdos_dir_entry *) (bh->b_data))[offset];
703 [i_pos & (sbi->dir_per_block - 1)];
704 if (S_ISDIR(inode->i_mode)) 704 if (S_ISDIR(inode->i_mode))
705 raw_entry->size = 0; 705 raw_entry->size = 0;
706 else 706 else
@@ -761,12 +761,6 @@ static const struct super_operations fat_sops = {
761 .show_options = fat_show_options, 761 .show_options = fat_show_options,
762}; 762};
763 763
764static const struct export_operations fat_export_ops = {
765 .fh_to_dentry = fat_fh_to_dentry,
766 .fh_to_parent = fat_fh_to_parent,
767 .get_parent = fat_get_parent,
768};
769
770static int fat_show_options(struct seq_file *m, struct dentry *root) 764static int fat_show_options(struct seq_file *m, struct dentry *root)
771{ 765{
772 struct msdos_sb_info *sbi = MSDOS_SB(root->d_sb); 766 struct msdos_sb_info *sbi = MSDOS_SB(root->d_sb);
@@ -814,8 +808,6 @@ static int fat_show_options(struct seq_file *m, struct dentry *root)
814 seq_puts(m, ",usefree"); 808 seq_puts(m, ",usefree");
815 if (opts->quiet) 809 if (opts->quiet)
816 seq_puts(m, ",quiet"); 810 seq_puts(m, ",quiet");
817 if (opts->nfs)
818 seq_puts(m, ",nfs");
819 if (opts->showexec) 811 if (opts->showexec)
820 seq_puts(m, ",showexec"); 812 seq_puts(m, ",showexec");
821 if (opts->sys_immutable) 813 if (opts->sys_immutable)
@@ -849,6 +841,10 @@ static int fat_show_options(struct seq_file *m, struct dentry *root)
849 seq_puts(m, ",errors=panic"); 841 seq_puts(m, ",errors=panic");
850 else 842 else
851 seq_puts(m, ",errors=remount-ro"); 843 seq_puts(m, ",errors=remount-ro");
844 if (opts->nfs == FAT_NFS_NOSTALE_RO)
845 seq_puts(m, ",nfs=nostale_ro");
846 else if (opts->nfs)
847 seq_puts(m, ",nfs=stale_rw");
852 if (opts->discard) 848 if (opts->discard)
853 seq_puts(m, ",discard"); 849 seq_puts(m, ",discard");
854 850
@@ -865,7 +861,7 @@ enum {
865 Opt_uni_xl_no, Opt_uni_xl_yes, Opt_nonumtail_no, Opt_nonumtail_yes, 861 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, 862 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, 863 Opt_err_panic, Opt_err_ro, Opt_discard, Opt_nfs, Opt_time_offset,
868 Opt_err, 864 Opt_nfs_stale_rw, Opt_nfs_nostale_ro, Opt_err,
869}; 865};
870 866
871static const match_table_t fat_tokens = { 867static const match_table_t fat_tokens = {
@@ -895,7 +891,9 @@ static const match_table_t fat_tokens = {
895 {Opt_err_panic, "errors=panic"}, 891 {Opt_err_panic, "errors=panic"},
896 {Opt_err_ro, "errors=remount-ro"}, 892 {Opt_err_ro, "errors=remount-ro"},
897 {Opt_discard, "discard"}, 893 {Opt_discard, "discard"},
898 {Opt_nfs, "nfs"}, 894 {Opt_nfs_stale_rw, "nfs"},
895 {Opt_nfs_stale_rw, "nfs=stale_rw"},
896 {Opt_nfs_nostale_ro, "nfs=nostale_ro"},
899 {Opt_obsolete, "conv=binary"}, 897 {Opt_obsolete, "conv=binary"},
900 {Opt_obsolete, "conv=text"}, 898 {Opt_obsolete, "conv=text"},
901 {Opt_obsolete, "conv=auto"}, 899 {Opt_obsolete, "conv=auto"},
@@ -1092,6 +1090,12 @@ static int parse_options(struct super_block *sb, char *options, int is_vfat,
1092 case Opt_err_ro: 1090 case Opt_err_ro:
1093 opts->errors = FAT_ERRORS_RO; 1091 opts->errors = FAT_ERRORS_RO;
1094 break; 1092 break;
1093 case Opt_nfs_stale_rw:
1094 opts->nfs = FAT_NFS_STALE_RW;
1095 break;
1096 case Opt_nfs_nostale_ro:
1097 opts->nfs = FAT_NFS_NOSTALE_RO;
1098 break;
1095 1099
1096 /* msdos specific */ 1100 /* msdos specific */
1097 case Opt_dots: 1101 case Opt_dots:
@@ -1150,9 +1154,6 @@ static int parse_options(struct super_block *sb, char *options, int is_vfat,
1150 case Opt_discard: 1154 case Opt_discard:
1151 opts->discard = 1; 1155 opts->discard = 1;
1152 break; 1156 break;
1153 case Opt_nfs:
1154 opts->nfs = 1;
1155 break;
1156 1157
1157 /* obsolete mount options */ 1158 /* obsolete mount options */
1158 case Opt_obsolete: 1159 case Opt_obsolete:
@@ -1183,6 +1184,10 @@ out:
1183 opts->allow_utime = ~opts->fs_dmask & (S_IWGRP | S_IWOTH); 1184 opts->allow_utime = ~opts->fs_dmask & (S_IWGRP | S_IWOTH);
1184 if (opts->unicode_xlate) 1185 if (opts->unicode_xlate)
1185 opts->utf8 = 0; 1186 opts->utf8 = 0;
1187 if (opts->nfs == FAT_NFS_NOSTALE_RO) {
1188 sb->s_flags |= MS_RDONLY;
1189 sb->s_export_op = &fat_export_ops_nostale;
1190 }
1186 1191
1187 return 0; 1192 return 0;
1188} 1193}
@@ -1193,7 +1198,7 @@ static int fat_read_root(struct inode *inode)
1193 struct msdos_sb_info *sbi = MSDOS_SB(sb); 1198 struct msdos_sb_info *sbi = MSDOS_SB(sb);
1194 int error; 1199 int error;
1195 1200
1196 MSDOS_I(inode)->i_pos = 0; 1201 MSDOS_I(inode)->i_pos = MSDOS_ROOT_INO;
1197 inode->i_uid = sbi->options.fs_uid; 1202 inode->i_uid = sbi->options.fs_uid;
1198 inode->i_gid = sbi->options.fs_gid; 1203 inode->i_gid = sbi->options.fs_gid;
1199 inode->i_version++; 1204 inode->i_version++;
@@ -1256,6 +1261,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat,
1256 sb->s_magic = MSDOS_SUPER_MAGIC; 1261 sb->s_magic = MSDOS_SUPER_MAGIC;
1257 sb->s_op = &fat_sops; 1262 sb->s_op = &fat_sops;
1258 sb->s_export_op = &fat_export_ops; 1263 sb->s_export_op = &fat_export_ops;
1264 mutex_init(&sbi->nfs_build_inode_lock);
1259 ratelimit_state_init(&sbi->ratelimit, DEFAULT_RATELIMIT_INTERVAL, 1265 ratelimit_state_init(&sbi->ratelimit, DEFAULT_RATELIMIT_INTERVAL,
1260 DEFAULT_RATELIMIT_BURST); 1266 DEFAULT_RATELIMIT_BURST);
1261 1267