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.c187
1 files changed, 55 insertions, 132 deletions
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index 4e5a6ac54ebd..76f60c642c06 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -281,15 +281,42 @@ static inline unsigned long fat_hash(loff_t i_pos)
281 return hash_32(i_pos, FAT_HASH_BITS); 281 return hash_32(i_pos, FAT_HASH_BITS);
282} 282}
283 283
284static void dir_hash_init(struct super_block *sb)
285{
286 struct msdos_sb_info *sbi = MSDOS_SB(sb);
287 int i;
288
289 spin_lock_init(&sbi->dir_hash_lock);
290 for (i = 0; i < FAT_HASH_SIZE; i++)
291 INIT_HLIST_HEAD(&sbi->dir_hashtable[i]);
292}
293
284void fat_attach(struct inode *inode, loff_t i_pos) 294void fat_attach(struct inode *inode, loff_t i_pos)
285{ 295{
286 struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb); 296 struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
287 struct hlist_head *head = sbi->inode_hashtable + fat_hash(i_pos);
288 297
289 spin_lock(&sbi->inode_hash_lock); 298 if (inode->i_ino != MSDOS_ROOT_INO) {
290 MSDOS_I(inode)->i_pos = i_pos; 299 struct hlist_head *head = sbi->inode_hashtable
291 hlist_add_head(&MSDOS_I(inode)->i_fat_hash, head); 300 + fat_hash(i_pos);
292 spin_unlock(&sbi->inode_hash_lock); 301
302 spin_lock(&sbi->inode_hash_lock);
303 MSDOS_I(inode)->i_pos = i_pos;
304 hlist_add_head(&MSDOS_I(inode)->i_fat_hash, head);
305 spin_unlock(&sbi->inode_hash_lock);
306 }
307
308 /* If NFS support is enabled, cache the mapping of start cluster
309 * to directory inode. This is used during reconnection of
310 * dentries to the filesystem root.
311 */
312 if (S_ISDIR(inode->i_mode) && sbi->options.nfs) {
313 struct hlist_head *d_head = sbi->dir_hashtable;
314 d_head += fat_dir_hash(MSDOS_I(inode)->i_logstart);
315
316 spin_lock(&sbi->dir_hash_lock);
317 hlist_add_head(&MSDOS_I(inode)->i_dir_hash, d_head);
318 spin_unlock(&sbi->dir_hash_lock);
319 }
293} 320}
294EXPORT_SYMBOL_GPL(fat_attach); 321EXPORT_SYMBOL_GPL(fat_attach);
295 322
@@ -300,6 +327,12 @@ void fat_detach(struct inode *inode)
300 MSDOS_I(inode)->i_pos = 0; 327 MSDOS_I(inode)->i_pos = 0;
301 hlist_del_init(&MSDOS_I(inode)->i_fat_hash); 328 hlist_del_init(&MSDOS_I(inode)->i_fat_hash);
302 spin_unlock(&sbi->inode_hash_lock); 329 spin_unlock(&sbi->inode_hash_lock);
330
331 if (S_ISDIR(inode->i_mode) && sbi->options.nfs) {
332 spin_lock(&sbi->dir_hash_lock);
333 hlist_del_init(&MSDOS_I(inode)->i_dir_hash);
334 spin_unlock(&sbi->dir_hash_lock);
335 }
303} 336}
304EXPORT_SYMBOL_GPL(fat_detach); 337EXPORT_SYMBOL_GPL(fat_detach);
305 338
@@ -504,6 +537,7 @@ static void init_once(void *foo)
504 ei->cache_valid_id = FAT_CACHE_VALID + 1; 537 ei->cache_valid_id = FAT_CACHE_VALID + 1;
505 INIT_LIST_HEAD(&ei->cache_lru); 538 INIT_LIST_HEAD(&ei->cache_lru);
506 INIT_HLIST_NODE(&ei->i_fat_hash); 539 INIT_HLIST_NODE(&ei->i_fat_hash);
540 INIT_HLIST_NODE(&ei->i_dir_hash);
507 inode_init_once(&ei->vfs_inode); 541 inode_init_once(&ei->vfs_inode);
508} 542}
509 543
@@ -668,125 +702,9 @@ static const struct super_operations fat_sops = {
668 .show_options = fat_show_options, 702 .show_options = fat_show_options,
669}; 703};
670 704
671/*
672 * a FAT file handle with fhtype 3 is
673 * 0/ i_ino - for fast, reliable lookup if still in the cache
674 * 1/ i_generation - to see if i_ino is still valid
675 * bit 0 == 0 iff directory
676 * 2/ i_pos(8-39) - if ino has changed, but still in cache
677 * 3/ i_pos(4-7)|i_logstart - to semi-verify inode found at i_pos
678 * 4/ i_pos(0-3)|parent->i_logstart - maybe used to hunt for the file on disc
679 *
680 * Hack for NFSv2: Maximum FAT entry number is 28bits and maximum
681 * i_pos is 40bits (blocknr(32) + dir offset(8)), so two 4bits
682 * of i_logstart is used to store the directory entry offset.
683 */
684
685static struct dentry *fat_fh_to_dentry(struct super_block *sb,
686 struct fid *fid, int fh_len, int fh_type)
687{
688 struct inode *inode = NULL;
689 u32 *fh = fid->raw;
690
691 if (fh_len < 5 || fh_type != 3)
692 return NULL;
693
694 inode = ilookup(sb, fh[0]);
695 if (!inode || inode->i_generation != fh[1]) {
696 if (inode)
697 iput(inode);
698 inode = NULL;
699 }
700 if (!inode) {
701 loff_t i_pos;
702 int i_logstart = fh[3] & 0x0fffffff;
703
704 i_pos = (loff_t)fh[2] << 8;
705 i_pos |= ((fh[3] >> 24) & 0xf0) | (fh[4] >> 28);
706
707 /* try 2 - see if i_pos is in F-d-c
708 * require i_logstart to be the same
709 * Will fail if you truncate and then re-write
710 */
711
712 inode = fat_iget(sb, i_pos);
713 if (inode && MSDOS_I(inode)->i_logstart != i_logstart) {
714 iput(inode);
715 inode = NULL;
716 }
717 }
718
719 /*
720 * For now, do nothing if the inode is not found.
721 *
722 * What we could do is:
723 *
724 * - follow the file starting at fh[4], and record the ".." entry,
725 * and the name of the fh[2] entry.
726 * - then follow the ".." file finding the next step up.
727 *
728 * This way we build a path to the root of the tree. If this works, we
729 * lookup the path and so get this inode into the cache. Finally try
730 * the fat_iget lookup again. If that fails, then we are totally out
731 * of luck. But all that is for another day
732 */
733 return d_obtain_alias(inode);
734}
735
736static int
737fat_encode_fh(struct inode *inode, __u32 *fh, int *lenp, struct inode *parent)
738{
739 int len = *lenp;
740 struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
741 loff_t i_pos;
742
743 if (len < 5) {
744 *lenp = 5;
745 return 255; /* no room */
746 }
747
748 i_pos = fat_i_pos_read(sbi, inode);
749 *lenp = 5;
750 fh[0] = inode->i_ino;
751 fh[1] = inode->i_generation;
752 fh[2] = i_pos >> 8;
753 fh[3] = ((i_pos & 0xf0) << 24) | MSDOS_I(inode)->i_logstart;
754 fh[4] = (i_pos & 0x0f) << 28;
755 if (parent)
756 fh[4] |= MSDOS_I(parent)->i_logstart;
757 return 3;
758}
759
760static struct dentry *fat_get_parent(struct dentry *child)
761{
762 struct super_block *sb = child->d_sb;
763 struct buffer_head *bh;
764 struct msdos_dir_entry *de;
765 loff_t i_pos;
766 struct dentry *parent;
767 struct inode *inode;
768 int err;
769
770 lock_super(sb);
771
772 err = fat_get_dotdot_entry(child->d_inode, &bh, &de, &i_pos);
773 if (err) {
774 parent = ERR_PTR(err);
775 goto out;
776 }
777 inode = fat_build_inode(sb, de, i_pos);
778 brelse(bh);
779
780 parent = d_obtain_alias(inode);
781out:
782 unlock_super(sb);
783
784 return parent;
785}
786
787static const struct export_operations fat_export_ops = { 705static const struct export_operations fat_export_ops = {
788 .encode_fh = fat_encode_fh,
789 .fh_to_dentry = fat_fh_to_dentry, 706 .fh_to_dentry = fat_fh_to_dentry,
707 .fh_to_parent = fat_fh_to_parent,
790 .get_parent = fat_get_parent, 708 .get_parent = fat_get_parent,
791}; 709};
792 710
@@ -836,6 +754,8 @@ static int fat_show_options(struct seq_file *m, struct dentry *root)
836 seq_puts(m, ",usefree"); 754 seq_puts(m, ",usefree");
837 if (opts->quiet) 755 if (opts->quiet)
838 seq_puts(m, ",quiet"); 756 seq_puts(m, ",quiet");
757 if (opts->nfs)
758 seq_puts(m, ",nfs");
839 if (opts->showexec) 759 if (opts->showexec)
840 seq_puts(m, ",showexec"); 760 seq_puts(m, ",showexec");
841 if (opts->sys_immutable) 761 if (opts->sys_immutable)
@@ -880,7 +800,7 @@ enum {
880 Opt_shortname_winnt, Opt_shortname_mixed, Opt_utf8_no, Opt_utf8_yes, 800 Opt_shortname_winnt, Opt_shortname_mixed, Opt_utf8_no, Opt_utf8_yes,
881 Opt_uni_xl_no, Opt_uni_xl_yes, Opt_nonumtail_no, Opt_nonumtail_yes, 801 Opt_uni_xl_no, Opt_uni_xl_yes, Opt_nonumtail_no, Opt_nonumtail_yes,
882 Opt_obsolete, Opt_flush, Opt_tz_utc, Opt_rodir, Opt_err_cont, 802 Opt_obsolete, Opt_flush, Opt_tz_utc, Opt_rodir, Opt_err_cont,
883 Opt_err_panic, Opt_err_ro, Opt_discard, Opt_err, 803 Opt_err_panic, Opt_err_ro, Opt_discard, Opt_nfs, Opt_err,
884}; 804};
885 805
886static const match_table_t fat_tokens = { 806static const match_table_t fat_tokens = {
@@ -909,6 +829,7 @@ static const match_table_t fat_tokens = {
909 {Opt_err_panic, "errors=panic"}, 829 {Opt_err_panic, "errors=panic"},
910 {Opt_err_ro, "errors=remount-ro"}, 830 {Opt_err_ro, "errors=remount-ro"},
911 {Opt_discard, "discard"}, 831 {Opt_discard, "discard"},
832 {Opt_nfs, "nfs"},
912 {Opt_obsolete, "conv=binary"}, 833 {Opt_obsolete, "conv=binary"},
913 {Opt_obsolete, "conv=text"}, 834 {Opt_obsolete, "conv=text"},
914 {Opt_obsolete, "conv=auto"}, 835 {Opt_obsolete, "conv=auto"},
@@ -989,6 +910,7 @@ static int parse_options(struct super_block *sb, char *options, int is_vfat,
989 opts->numtail = 1; 910 opts->numtail = 1;
990 opts->usefree = opts->nocase = 0; 911 opts->usefree = opts->nocase = 0;
991 opts->tz_utc = 0; 912 opts->tz_utc = 0;
913 opts->nfs = 0;
992 opts->errors = FAT_ERRORS_RO; 914 opts->errors = FAT_ERRORS_RO;
993 *debug = 0; 915 *debug = 0;
994 916
@@ -1153,6 +1075,9 @@ static int parse_options(struct super_block *sb, char *options, int is_vfat,
1153 case Opt_discard: 1075 case Opt_discard:
1154 opts->discard = 1; 1076 opts->discard = 1;
1155 break; 1077 break;
1078 case Opt_nfs:
1079 opts->nfs = 1;
1080 break;
1156 1081
1157 /* obsolete mount options */ 1082 /* obsolete mount options */
1158 case Opt_obsolete: 1083 case Opt_obsolete:
@@ -1443,6 +1368,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat,
1443 1368
1444 /* set up enough so that it can read an inode */ 1369 /* set up enough so that it can read an inode */
1445 fat_hash_init(sb); 1370 fat_hash_init(sb);
1371 dir_hash_init(sb);
1446 fat_ent_access_init(sb); 1372 fat_ent_access_init(sb);
1447 1373
1448 /* 1374 /*
@@ -1497,6 +1423,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat,
1497 } 1423 }
1498 error = -ENOMEM; 1424 error = -ENOMEM;
1499 insert_inode_hash(root_inode); 1425 insert_inode_hash(root_inode);
1426 fat_attach(root_inode, 0);
1500 sb->s_root = d_make_root(root_inode); 1427 sb->s_root = d_make_root(root_inode);
1501 if (!sb->s_root) { 1428 if (!sb->s_root) {
1502 fat_msg(sb, KERN_ERR, "get root inode failed"); 1429 fat_msg(sb, KERN_ERR, "get root inode failed");
@@ -1536,18 +1463,14 @@ static int writeback_inode(struct inode *inode)
1536{ 1463{
1537 1464
1538 int ret; 1465 int ret;
1539 struct address_space *mapping = inode->i_mapping; 1466
1540 struct writeback_control wbc = { 1467 /* if we used wait=1, sync_inode_metadata waits for the io for the
1541 .sync_mode = WB_SYNC_NONE, 1468 * inode to finish. So wait=0 is sent down to sync_inode_metadata
1542 .nr_to_write = 0,
1543 };
1544 /* if we used WB_SYNC_ALL, sync_inode waits for the io for the
1545 * inode to finish. So WB_SYNC_NONE is sent down to sync_inode
1546 * and filemap_fdatawrite is used for the data blocks 1469 * and filemap_fdatawrite is used for the data blocks
1547 */ 1470 */
1548 ret = sync_inode(inode, &wbc); 1471 ret = sync_inode_metadata(inode, 0);
1549 if (!ret) 1472 if (!ret)
1550 ret = filemap_fdatawrite(mapping); 1473 ret = filemap_fdatawrite(inode->i_mapping);
1551 return ret; 1474 return ret;
1552} 1475}
1553 1476