From: Chris Mason <mason@suse.com>
To: linux-fsdevel@vger.kernel.org, akpm@osdl.org
Subject: [PATCH] add -o flush for fat
Date: Fri, 4 Aug 2006 15:27:21 -0400 [thread overview]
Message-ID: <20060804192721.GF1048@watt.suse.com> (raw)
From: Chris Mason <mason@suse.com>
Subject: 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>
--- a/fs/fat/file.c Fri Aug 04 14:02:26 2006 -0400
+++ b/fs/fat/file.c Fri Aug 04 15:25:09 2006 -0400
@@ -13,6 +13,7 @@
#include <linux/smp_lock.h>
#include <linux/buffer_head.h>
#include <linux/writeback.h>
+#include <linux/blkdev.h>
int fat_generic_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
@@ -112,6 +113,17 @@ int fat_generic_ioctl(struct inode *inod
}
}
+static int fat_file_release(struct inode *inode, struct file *filp)
+{
+ if ((filp->f_mode & FMODE_WRITE) &&
+ MSDOS_SB(inode->i_sb)->options.flush) {
+ writeback_inode(inode);
+ writeback_bdev(inode->i_sb);
+ blk_congestion_wait(WRITE, HZ/10);
+ }
+ return 0;
+}
+
const struct file_operations fat_file_operations = {
.llseek = generic_file_llseek,
.read = do_sync_read,
@@ -121,6 +133,7 @@ const struct file_operations fat_file_op
.aio_read = generic_file_aio_read,
.aio_write = generic_file_aio_write,
.mmap = generic_file_mmap,
+ .release = fat_file_release,
.ioctl = fat_generic_ioctl,
.fsync = file_fsync,
.sendfile = generic_file_sendfile,
@@ -289,6 +302,10 @@ void fat_truncate(struct inode *inode)
lock_kernel();
fat_free(inode, nr_clusters);
unlock_kernel();
+ if (MSDOS_SB(inode->i_sb)->options.flush) {
+ writeback_inode(inode);
+ writeback_bdev(inode->i_sb);
+ }
}
struct inode_operations fat_file_inode_operations = {
--- a/fs/fat/inode.c Fri Aug 04 14:02:26 2006 -0400
+++ b/fs/fat/inode.c Fri Aug 04 14:02:26 2006 -0400
@@ -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
@@ -861,7 +862,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 = {
@@ -893,7 +894,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"},
@@ -1034,6 +1036,9 @@ static int parse_options(char *options,
return 0;
opts->codepage = option;
break;
+ case Opt_flush:
+ opts->flush = 1;
+ break;
/* msdos specific */
case Opt_dots:
--- a/fs/fs-writeback.c Fri Aug 04 14:02:26 2006 -0400
+++ b/fs/fs-writeback.c Fri Aug 04 14:41:46 2006 -0400
@@ -391,6 +391,41 @@ sync_sb_inodes(struct super_block *sb, s
}
/*
+ * starts IO on any dirty blocks in the block device. This uses
+ * filemap_flush, and so it does not wait for the io to finish, and does
+ * not wait on any IO currently in flight.
+ */
+void writeback_bdev(struct super_block *sb)
+{
+ struct address_space *mapping = sb->s_bdev->bd_inode->i_mapping;
+ filemap_flush(mapping);
+}
+EXPORT_SYMBOL_GPL(writeback_bdev);
+
+/*
+ * start writeback on both the inode and the data blocks.
+ * filemap_fdatawrite is used, so it waits for any IO that was in
+ * flight for dirty blocks at the start of this call. This will not
+ * wait for any IO it starts.
+ */
+void writeback_inode(struct inode *inode)
+{
+
+ 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
+ */
+ sync_inode(inode, &wbc);
+ filemap_fdatawrite(mapping);
+}
+EXPORT_SYMBOL_GPL(writeback_inode);
+
+/*
* Start writeback of dirty pagecache data against all unlocked inodes.
*
* Note:
--- a/fs/msdos/namei.c Fri Aug 04 14:02:26 2006 -0400
+++ b/fs/msdos/namei.c Fri Aug 04 14:02:26 2006 -0400
@@ -11,6 +11,7 @@
#include <linux/buffer_head.h>
#include <linux/msdos_fs.h>
#include <linux/smp_lock.h>
+#include <linux/writeback.h>
/* Characters that are undesirable in an MS-DOS file name */
static unsigned char bad_chars[] = "*?<>|\"";
@@ -280,7 +281,7 @@ static int msdos_create(struct inode *di
struct nameidata *nd)
{
struct super_block *sb = dir->i_sb;
- struct inode *inode;
+ struct inode *inode = NULL;
struct fat_slot_info sinfo;
struct timespec ts;
unsigned char msdos_name[MSDOS_NAME];
@@ -316,6 +317,11 @@ static int msdos_create(struct inode *di
d_instantiate(dentry, inode);
out:
unlock_kernel();
+ if (!err && MSDOS_SB(sb)->options.flush) {
+ writeback_inode(dir);
+ writeback_inode(inode);
+ writeback_bdev(sb);
+ }
return err;
}
@@ -348,6 +354,11 @@ static int msdos_rmdir(struct inode *dir
fat_detach(inode);
out:
unlock_kernel();
+ if (!err && MSDOS_SB(inode->i_sb)->options.flush) {
+ writeback_inode(dir);
+ writeback_inode(inode);
+ writeback_bdev(inode->i_sb);
+ }
return err;
}
@@ -401,6 +412,11 @@ static int msdos_mkdir(struct inode *dir
d_instantiate(dentry, inode);
unlock_kernel();
+ if (MSDOS_SB(sb)->options.flush) {
+ writeback_inode(dir);
+ writeback_inode(inode);
+ writeback_bdev(sb);
+ }
return 0;
out_free:
@@ -430,6 +446,11 @@ static int msdos_unlink(struct inode *di
fat_detach(inode);
out:
unlock_kernel();
+ if (!err && MSDOS_SB(inode->i_sb)->options.flush) {
+ writeback_inode(dir);
+ writeback_inode(inode);
+ writeback_bdev(inode->i_sb);
+ }
return err;
}
@@ -635,6 +656,11 @@ static int msdos_rename(struct inode *ol
new_dir, new_msdos_name, new_dentry, is_hid);
out:
unlock_kernel();
+ if (!err && MSDOS_SB(old_dir->i_sb)->options.flush) {
+ writeback_inode(old_dir);
+ writeback_inode(new_dir);
+ writeback_bdev(old_dir->i_sb);
+ }
return err;
}
--- a/include/linux/msdos_fs.h Fri Aug 04 14:02:26 2006 -0400
+++ b/include/linux/msdos_fs.h Fri Aug 04 14:02:26 2006 -0400
@@ -204,6 +204,7 @@ struct fat_mount_options {
unicode_xlate:1, /* create escape sequences for unhandled Unicode */
numtail:1, /* Does first alias have a numeric '~1' type tail? */
atari:1, /* Use Atari GEMDOS variation of MS-DOS fs */
+ flush:1, /* write things quickly */
nocase:1; /* Does this need case conversion? 0=need case conversion*/
};
--- a/include/linux/writeback.h Fri Aug 04 14:02:26 2006 -0400
+++ b/include/linux/writeback.h Fri Aug 04 14:02:26 2006 -0400
@@ -69,6 +69,8 @@ int inode_wait(void *);
int inode_wait(void *);
void sync_inodes_sb(struct super_block *, int wait);
void sync_inodes(int wait);
+void writeback_bdev(struct super_block *);
+void writeback_inode(struct inode *);
/* writeback.h requires fs.h; it, too, is not included from here. */
static inline void wait_on_inode(struct inode *inode)
next reply other threads:[~2006-08-04 19:27 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-08-04 19:27 Chris Mason [this message]
2006-08-05 1:31 ` [PATCH] add -o flush for fat Andrew Morton
2006-08-05 12:26 ` Chris Mason
2006-08-05 19:12 ` Andrew Morton
2006-08-05 20:54 ` OGAWA Hirofumi
2006-08-07 20:23 ` Chris Mason
2006-08-07 23:58 ` Andrew Morton
2006-08-08 8:05 ` Chris Mason
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20060804192721.GF1048@watt.suse.com \
--to=mason@suse.com \
--cc=akpm@osdl.org \
--cc=linux-fsdevel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).