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.c99
1 files changed, 72 insertions, 27 deletions
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index 7c35d582ec10..045738032a83 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -24,6 +24,7 @@
24#include <linux/vfs.h> 24#include <linux/vfs.h>
25#include <linux/parser.h> 25#include <linux/parser.h>
26#include <linux/uio.h> 26#include <linux/uio.h>
27#include <linux/writeback.h>
27#include <asm/unaligned.h> 28#include <asm/unaligned.h>
28 29
29#ifndef CONFIG_FAT_DEFAULT_IOCHARSET 30#ifndef CONFIG_FAT_DEFAULT_IOCHARSET
@@ -50,14 +51,14 @@ static int fat_add_cluster(struct inode *inode)
50 return err; 51 return err;
51} 52}
52 53
53static int __fat_get_blocks(struct inode *inode, sector_t iblock, 54static inline int __fat_get_block(struct inode *inode, sector_t iblock,
54 unsigned long *max_blocks, 55 unsigned long *max_blocks,
55 struct buffer_head *bh_result, int create) 56 struct buffer_head *bh_result, int create)
56{ 57{
57 struct super_block *sb = inode->i_sb; 58 struct super_block *sb = inode->i_sb;
58 struct msdos_sb_info *sbi = MSDOS_SB(sb); 59 struct msdos_sb_info *sbi = MSDOS_SB(sb);
59 sector_t phys;
60 unsigned long mapped_blocks; 60 unsigned long mapped_blocks;
61 sector_t phys;
61 int err, offset; 62 int err, offset;
62 63
63 err = fat_bmap(inode, iblock, &phys, &mapped_blocks); 64 err = fat_bmap(inode, iblock, &phys, &mapped_blocks);
@@ -73,7 +74,7 @@ static int __fat_get_blocks(struct inode *inode, sector_t iblock,
73 74
74 if (iblock != MSDOS_I(inode)->mmu_private >> sb->s_blocksize_bits) { 75 if (iblock != MSDOS_I(inode)->mmu_private >> sb->s_blocksize_bits) {
75 fat_fs_panic(sb, "corrupted file size (i_pos %lld, %lld)", 76 fat_fs_panic(sb, "corrupted file size (i_pos %lld, %lld)",
76 MSDOS_I(inode)->i_pos, MSDOS_I(inode)->mmu_private); 77 MSDOS_I(inode)->i_pos, MSDOS_I(inode)->mmu_private);
77 return -EIO; 78 return -EIO;
78 } 79 }
79 80
@@ -93,34 +94,29 @@ static int __fat_get_blocks(struct inode *inode, sector_t iblock,
93 err = fat_bmap(inode, iblock, &phys, &mapped_blocks); 94 err = fat_bmap(inode, iblock, &phys, &mapped_blocks);
94 if (err) 95 if (err)
95 return err; 96 return err;
97
96 BUG_ON(!phys); 98 BUG_ON(!phys);
97 BUG_ON(*max_blocks != mapped_blocks); 99 BUG_ON(*max_blocks != mapped_blocks);
98 set_buffer_new(bh_result); 100 set_buffer_new(bh_result);
99 map_bh(bh_result, sb, phys); 101 map_bh(bh_result, sb, phys);
102
100 return 0; 103 return 0;
101} 104}
102 105
103static int fat_get_blocks(struct inode *inode, sector_t iblock, 106static int fat_get_block(struct inode *inode, sector_t iblock,
104 struct buffer_head *bh_result, int create) 107 struct buffer_head *bh_result, int create)
105{ 108{
106 struct super_block *sb = inode->i_sb; 109 struct super_block *sb = inode->i_sb;
107 int err;
108 unsigned long max_blocks = bh_result->b_size >> inode->i_blkbits; 110 unsigned long max_blocks = bh_result->b_size >> inode->i_blkbits;
111 int err;
109 112
110 err = __fat_get_blocks(inode, iblock, &max_blocks, bh_result, create); 113 err = __fat_get_block(inode, iblock, &max_blocks, bh_result, create);
111 if (err) 114 if (err)
112 return err; 115 return err;
113 bh_result->b_size = max_blocks << sb->s_blocksize_bits; 116 bh_result->b_size = max_blocks << sb->s_blocksize_bits;
114 return 0; 117 return 0;
115} 118}
116 119
117static int fat_get_block(struct inode *inode, sector_t iblock,
118 struct buffer_head *bh_result, int create)
119{
120 unsigned long max_blocks = 1;
121 return __fat_get_blocks(inode, iblock, &max_blocks, bh_result, create);
122}
123
124static int fat_writepage(struct page *page, struct writeback_control *wbc) 120static int fat_writepage(struct page *page, struct writeback_control *wbc)
125{ 121{
126 return block_write_full_page(page, fat_get_block, wbc); 122 return block_write_full_page(page, fat_get_block, wbc);
@@ -188,7 +184,7 @@ static ssize_t fat_direct_IO(int rw, struct kiocb *iocb,
188 * condition of fat_get_block() and ->truncate(). 184 * condition of fat_get_block() and ->truncate().
189 */ 185 */
190 return blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov, 186 return blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
191 offset, nr_segs, fat_get_blocks, NULL); 187 offset, nr_segs, fat_get_block, NULL);
192} 188}
193 189
194static sector_t _fat_bmap(struct address_space *mapping, sector_t block) 190static sector_t _fat_bmap(struct address_space *mapping, sector_t block)
@@ -196,7 +192,7 @@ static sector_t _fat_bmap(struct address_space *mapping, sector_t block)
196 return generic_block_bmap(mapping, block, fat_get_block); 192 return generic_block_bmap(mapping, block, fat_get_block);
197} 193}
198 194
199static struct address_space_operations fat_aops = { 195static const struct address_space_operations fat_aops = {
200 .readpage = fat_readpage, 196 .readpage = fat_readpage,
201 .readpages = fat_readpages, 197 .readpages = fat_readpages,
202 .writepage = fat_writepage, 198 .writepage = fat_writepage,
@@ -375,8 +371,6 @@ static int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de)
375 inode->i_flags |= S_IMMUTABLE; 371 inode->i_flags |= S_IMMUTABLE;
376 } 372 }
377 MSDOS_I(inode)->i_attrs = de->attr & ATTR_UNUSED; 373 MSDOS_I(inode)->i_attrs = de->attr & ATTR_UNUSED;
378 /* this is as close to the truth as we can get ... */
379 inode->i_blksize = sbi->cluster_size;
380 inode->i_blocks = ((inode->i_size + (sbi->cluster_size - 1)) 374 inode->i_blocks = ((inode->i_size + (sbi->cluster_size - 1))
381 & ~((loff_t)sbi->cluster_size - 1)) >> 9; 375 & ~((loff_t)sbi->cluster_size - 1)) >> 9;
382 inode->i_mtime.tv_sec = 376 inode->i_mtime.tv_sec =
@@ -528,8 +522,7 @@ static int __init fat_init_inodecache(void)
528 522
529static void __exit fat_destroy_inodecache(void) 523static void __exit fat_destroy_inodecache(void)
530{ 524{
531 if (kmem_cache_destroy(fat_inode_cachep)) 525 kmem_cache_destroy(fat_inode_cachep);
532 printk(KERN_INFO "fat_inode_cache: not all structures were freed\n");
533} 526}
534 527
535static int fat_remount(struct super_block *sb, int *flags, char *data) 528static int fat_remount(struct super_block *sb, int *flags, char *data)
@@ -861,7 +854,7 @@ enum {
861 Opt_charset, Opt_shortname_lower, Opt_shortname_win95, 854 Opt_charset, Opt_shortname_lower, Opt_shortname_win95,
862 Opt_shortname_winnt, Opt_shortname_mixed, Opt_utf8_no, Opt_utf8_yes, 855 Opt_shortname_winnt, Opt_shortname_mixed, Opt_utf8_no, Opt_utf8_yes,
863 Opt_uni_xl_no, Opt_uni_xl_yes, Opt_nonumtail_no, Opt_nonumtail_yes, 856 Opt_uni_xl_no, Opt_uni_xl_yes, Opt_nonumtail_no, Opt_nonumtail_yes,
864 Opt_obsolate, Opt_err, 857 Opt_obsolate, Opt_flush, Opt_err,
865}; 858};
866 859
867static match_table_t fat_tokens = { 860static match_table_t fat_tokens = {
@@ -893,7 +886,8 @@ static match_table_t fat_tokens = {
893 {Opt_obsolate, "cvf_format=%20s"}, 886 {Opt_obsolate, "cvf_format=%20s"},
894 {Opt_obsolate, "cvf_options=%100s"}, 887 {Opt_obsolate, "cvf_options=%100s"},
895 {Opt_obsolate, "posix"}, 888 {Opt_obsolate, "posix"},
896 {Opt_err, NULL} 889 {Opt_flush, "flush"},
890 {Opt_err, NULL},
897}; 891};
898static match_table_t msdos_tokens = { 892static match_table_t msdos_tokens = {
899 {Opt_nodots, "nodots"}, 893 {Opt_nodots, "nodots"},
@@ -1034,6 +1028,9 @@ static int parse_options(char *options, int is_vfat, int silent, int *debug,
1034 return 0; 1028 return 0;
1035 opts->codepage = option; 1029 opts->codepage = option;
1036 break; 1030 break;
1031 case Opt_flush:
1032 opts->flush = 1;
1033 break;
1037 1034
1038 /* msdos specific */ 1035 /* msdos specific */
1039 case Opt_dots: 1036 case Opt_dots:
@@ -1137,7 +1134,6 @@ static int fat_read_root(struct inode *inode)
1137 MSDOS_I(inode)->i_start = 0; 1134 MSDOS_I(inode)->i_start = 0;
1138 inode->i_size = sbi->dir_entries * sizeof(struct msdos_dir_entry); 1135 inode->i_size = sbi->dir_entries * sizeof(struct msdos_dir_entry);
1139 } 1136 }
1140 inode->i_blksize = sbi->cluster_size;
1141 inode->i_blocks = ((inode->i_size + (sbi->cluster_size - 1)) 1137 inode->i_blocks = ((inode->i_size + (sbi->cluster_size - 1))
1142 & ~((loff_t)sbi->cluster_size - 1)) >> 9; 1138 & ~((loff_t)sbi->cluster_size - 1)) >> 9;
1143 MSDOS_I(inode)->i_logstart = 0; 1139 MSDOS_I(inode)->i_logstart = 0;
@@ -1168,11 +1164,10 @@ int fat_fill_super(struct super_block *sb, void *data, int silent,
1168 long error; 1164 long error;
1169 char buf[50]; 1165 char buf[50];
1170 1166
1171 sbi = kmalloc(sizeof(struct msdos_sb_info), GFP_KERNEL); 1167 sbi = kzalloc(sizeof(struct msdos_sb_info), GFP_KERNEL);
1172 if (!sbi) 1168 if (!sbi)
1173 return -ENOMEM; 1169 return -ENOMEM;
1174 sb->s_fs_info = sbi; 1170 sb->s_fs_info = sbi;
1175 memset(sbi, 0, sizeof(struct msdos_sb_info));
1176 1171
1177 sb->s_flags |= MS_NODIRATIME; 1172 sb->s_flags |= MS_NODIRATIME;
1178 sb->s_magic = MSDOS_SUPER_MAGIC; 1173 sb->s_magic = MSDOS_SUPER_MAGIC;
@@ -1435,6 +1430,56 @@ out_fail:
1435 1430
1436EXPORT_SYMBOL_GPL(fat_fill_super); 1431EXPORT_SYMBOL_GPL(fat_fill_super);
1437 1432
1433/*
1434 * helper function for fat_flush_inodes. This writes both the inode
1435 * and the file data blocks, waiting for in flight data blocks before
1436 * the start of the call. It does not wait for any io started
1437 * during the call
1438 */
1439static int writeback_inode(struct inode *inode)
1440{
1441
1442 int ret;
1443 struct address_space *mapping = inode->i_mapping;
1444 struct writeback_control wbc = {
1445 .sync_mode = WB_SYNC_NONE,
1446 .nr_to_write = 0,
1447 };
1448 /* if we used WB_SYNC_ALL, sync_inode waits for the io for the
1449 * inode to finish. So WB_SYNC_NONE is sent down to sync_inode
1450 * and filemap_fdatawrite is used for the data blocks
1451 */
1452 ret = sync_inode(inode, &wbc);
1453 if (!ret)
1454 ret = filemap_fdatawrite(mapping);
1455 return ret;
1456}
1457
1458/*
1459 * write data and metadata corresponding to i1 and i2. The io is
1460 * started but we do not wait for any of it to finish.
1461 *
1462 * filemap_flush is used for the block device, so if there is a dirty
1463 * page for a block already in flight, we will not wait and start the
1464 * io over again
1465 */
1466int fat_flush_inodes(struct super_block *sb, struct inode *i1, struct inode *i2)
1467{
1468 int ret = 0;
1469 if (!MSDOS_SB(sb)->options.flush)
1470 return 0;
1471 if (i1)
1472 ret = writeback_inode(i1);
1473 if (!ret && i2)
1474 ret = writeback_inode(i2);
1475 if (!ret && sb) {
1476 struct address_space *mapping = sb->s_bdev->bd_inode->i_mapping;
1477 ret = filemap_flush(mapping);
1478 }
1479 return ret;
1480}
1481EXPORT_SYMBOL_GPL(fat_flush_inodes);
1482
1438static int __init init_fat_fs(void) 1483static int __init init_fat_fs(void)
1439{ 1484{
1440 int err; 1485 int err;