[PATCH] add -o flush for fat
Fat is commonly used on removable media. Mounting with -o flush tells the FS to write things to disk as quickly as possible. It is like -o sync, but much faster (and not as safe). Signed-off-by: Chris Mason <mason@suse.com> Cc: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:

committed by
Linus Torvalds

parent
6b77df08a3
commit
ae78bf9c4f
@@ -24,6 +24,7 @@
|
||||
#include <linux/vfs.h>
|
||||
#include <linux/parser.h>
|
||||
#include <linux/uio.h>
|
||||
#include <linux/writeback.h>
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
#ifndef CONFIG_FAT_DEFAULT_IOCHARSET
|
||||
@@ -853,7 +854,7 @@ enum {
|
||||
Opt_charset, Opt_shortname_lower, Opt_shortname_win95,
|
||||
Opt_shortname_winnt, Opt_shortname_mixed, Opt_utf8_no, Opt_utf8_yes,
|
||||
Opt_uni_xl_no, Opt_uni_xl_yes, Opt_nonumtail_no, Opt_nonumtail_yes,
|
||||
Opt_obsolate, Opt_err,
|
||||
Opt_obsolate, Opt_flush, Opt_err,
|
||||
};
|
||||
|
||||
static match_table_t fat_tokens = {
|
||||
@@ -885,7 +886,8 @@ static match_table_t fat_tokens = {
|
||||
{Opt_obsolate, "cvf_format=%20s"},
|
||||
{Opt_obsolate, "cvf_options=%100s"},
|
||||
{Opt_obsolate, "posix"},
|
||||
{Opt_err, NULL}
|
||||
{Opt_flush, "flush"},
|
||||
{Opt_err, NULL},
|
||||
};
|
||||
static match_table_t msdos_tokens = {
|
||||
{Opt_nodots, "nodots"},
|
||||
@@ -1026,6 +1028,9 @@ static int parse_options(char *options, int is_vfat, int silent, int *debug,
|
||||
return 0;
|
||||
opts->codepage = option;
|
||||
break;
|
||||
case Opt_flush:
|
||||
opts->flush = 1;
|
||||
break;
|
||||
|
||||
/* msdos specific */
|
||||
case Opt_dots:
|
||||
@@ -1425,6 +1430,56 @@ out_fail:
|
||||
|
||||
EXPORT_SYMBOL_GPL(fat_fill_super);
|
||||
|
||||
/*
|
||||
* helper function for fat_flush_inodes. This writes both the inode
|
||||
* and the file data blocks, waiting for in flight data blocks before
|
||||
* the start of the call. It does not wait for any io started
|
||||
* during the call
|
||||
*/
|
||||
static int writeback_inode(struct inode *inode)
|
||||
{
|
||||
|
||||
int ret;
|
||||
struct address_space *mapping = inode->i_mapping;
|
||||
struct writeback_control wbc = {
|
||||
.sync_mode = WB_SYNC_NONE,
|
||||
.nr_to_write = 0,
|
||||
};
|
||||
/* if we used WB_SYNC_ALL, sync_inode waits for the io for the
|
||||
* inode to finish. So WB_SYNC_NONE is sent down to sync_inode
|
||||
* and filemap_fdatawrite is used for the data blocks
|
||||
*/
|
||||
ret = sync_inode(inode, &wbc);
|
||||
if (!ret)
|
||||
ret = filemap_fdatawrite(mapping);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* write data and metadata corresponding to i1 and i2. The io is
|
||||
* started but we do not wait for any of it to finish.
|
||||
*
|
||||
* filemap_flush is used for the block device, so if there is a dirty
|
||||
* page for a block already in flight, we will not wait and start the
|
||||
* io over again
|
||||
*/
|
||||
int fat_flush_inodes(struct super_block *sb, struct inode *i1, struct inode *i2)
|
||||
{
|
||||
int ret = 0;
|
||||
if (!MSDOS_SB(sb)->options.flush)
|
||||
return 0;
|
||||
if (i1)
|
||||
ret = writeback_inode(i1);
|
||||
if (!ret && i2)
|
||||
ret = writeback_inode(i2);
|
||||
if (!ret && sb) {
|
||||
struct address_space *mapping = sb->s_bdev->bd_inode->i_mapping;
|
||||
ret = filemap_flush(mapping);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(fat_flush_inodes);
|
||||
|
||||
static int __init init_fat_fs(void)
|
||||
{
|
||||
int err;
|
||||
|
Reference in New Issue
Block a user