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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.