From: Holden Karau <holdenk@xandros.com>
To: Josef Sipek <jsipek@fsl.cs.sunysb.edu>
Cc: hirofumi@mail.parknet.co.jp, linux-kernel@vger.kernel.org,
"Holden Karau" <holdenk@xandros.com>,
"akpm@osdl.org" <akpm@osdl.org>,
linux-fsdevel@vger.kernel.org, holden@pigscanfly.ca,
holden.karau@gmail.com, "Nick Piggin" <nickpiggin@yahoo.com.au>,
"Jörn Engel" <joern@wohnheim.fh-wedel.de>,
"Josef Sipek" <jsipek@fsl.cs.sunysb.edu>
Subject: [PATCH 1/1] fat: improve sync performance by grouping writes revised
Date: Tue, 31 Oct 2006 10:03:08 -0500 [thread overview]
Message-ID: <454765AC.1050905@xandros.com> (raw)
From: Holden Karau <holden@pigscanfly.ca> http://www.holdenkarau.com
This is an attempt at improving fat_mirror_bhs in sync mode [namely it
writes all of the data for a backup block, and then blocks untill
finished]. The old behavior would write & block in smaller chunks, so
this should be slightly faster. It also removes the fix me requesting
that it be fixed to behave this way :-)
Signed-off-by: Holden Karau <holden@pigscanfly.ca>
---
This is an improved version of an earlier patch, I've cleaned up the
formatting and it now also groups the write for the primary fat block
[so even if the user has only 2 FATs it should still be slightly
faster]. If no one objects, I'd like to see if it would be possible to
put this in the -mm tree to make sure it doesn't eat anyones fs :-)
In case the patch gets mangled I've put it up at http://www.holdenkarau.com/~holden/projects/fat/001_improve_fat_sync_performance_revised.patch
And now for the actual patch:
--- a/fs/fat/fatent.c 2006-09-19 23:42:06.000000000 -0400
+++ b/fs/fat/fatent.c 2006-10-31 09:09:34.000000000 -0500
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2004, OGAWA Hirofumi
+ * Copyright (C) 2006, Holden Karau [Xandros]
* Released under GPL v2.
*/
@@ -343,52 +344,65 @@ int fat_ent_read(struct inode *inode, st
return ops->ent_get(fatent);
}
-/* FIXME: We can write the blocks as more big chunk. */
-static int fat_mirror_bhs(struct super_block *sb, struct buffer_head **bhs,
- int nr_bhs)
+
+static int fat_mirror_bhs_optw(struct super_block *sb, struct buffer_head **bhs,
+ int nr_bhs , int wait)
{
struct msdos_sb_info *sbi = MSDOS_SB(sb);
- struct buffer_head *c_bh;
+ struct buffer_head *c_bh[nr_bhs*(sbi->fats)];
int err, n, copy;
+ /* Always wait if mounted -o sync */
+ if (sb->s_flags & MS_SYNCHRONOUS )
+ wait = 1;
err = 0;
for (copy = 1; copy < sbi->fats; copy++) {
sector_t backup_fat = sbi->fat_length * copy;
-
- for (n = 0; n < nr_bhs; n++) {
- c_bh = sb_getblk(sb, backup_fat + bhs[n]->b_blocknr);
- if (!c_bh) {
+ for (n = 0 ; n < nr_bhs ; n++ ) {
+ c_bh[(copy-1)*nr_bhs+n] = sb_getblk(sb, backup_fat + bhs[n]->b_blocknr);
+ if (!c_bh[(copy-1)*nr_bhs+n]) {
+ printk(KERN_CRIT "fat: out of memory while copying backup fat. possible data loss\n");
err = -ENOMEM;
goto error;
}
- memcpy(c_bh->b_data, bhs[n]->b_data, sb->s_blocksize);
- set_buffer_uptodate(c_bh);
- mark_buffer_dirty(c_bh);
- if (sb->s_flags & MS_SYNCHRONOUS)
- err = sync_dirty_buffer(c_bh);
- brelse(c_bh);
- if (err)
- goto error;
+ memcpy(c_bh[(copy-1)*nr_bhs+n]->b_data, bhs[n]->b_data, sb->s_blocksize);
+ set_buffer_uptodate(c_bh[(copy-1)*nr_bhs+n]);
+ mark_buffer_dirty(c_bh[(copy-1)*nr_bhs+n]);
}
}
+
+ if (wait) {
+ for (n = 0 ; n < nr_bhs ; n++) {
+ printk("copying to %d to %d\n" ,n, nr_bhs*(sbi->fats-1)+n);
+ c_bh[nr_bhs*(sbi->fats-1)+n] = bhs[n];
+ printk("done , %p==%p\n" , c_bh[nr_bhs*(sbi->fats-1)+n] , bhs[n]);
+ }
+ }
+ err = fat_sync_bhs_optw( c_bh , nr_bhs*(sbi->fats+wait-1) , wait );
+ if (err)
+ goto error;
+ for (n = 0; n < nr_bhs*(sbi->fats-1); n++ ) {
+ brelse(c_bh[n]);
+ }
error:
return err;
}
+static inline int fat_mirror_bhs(struct super_block *sb, struct buffer_head **bhs,
+ int nr_bhs )
+{
+ return fat_mirror_bhs_optw(sb , bhs , nr_bhs, 0);
+}
+
+
int fat_ent_write(struct inode *inode, struct fat_entry *fatent,
int new, int wait)
{
struct super_block *sb = inode->i_sb;
struct fatent_operations *ops = MSDOS_SB(sb)->fatent_ops;
- int err;
ops->ent_put(fatent, new);
- if (wait) {
- err = fat_sync_bhs(fatent->bhs, fatent->nr_bhs);
- if (err)
- return err;
- }
- return fat_mirror_bhs(sb, fatent->bhs, fatent->nr_bhs);
+ return fat_mirror_bhs_optw(sb, fatent->bhs, fatent->nr_bhs , wait);
}
static inline int fat_ent_next(struct msdos_sb_info *sbi,
@@ -505,9 +519,9 @@ out:
fatent_brelse(&fatent);
if (!err) {
if (inode_needs_sync(inode))
- err = fat_sync_bhs(bhs, nr_bhs);
- if (!err)
- err = fat_mirror_bhs(sb, bhs, nr_bhs);
+ err = fat_mirror_bhs_optw(sb , bhs, nr_bhs , 1);
+ else
+ err = fat_mirror_bhs_optw(sb, bhs, nr_bhs , 0 );
}
for (i = 0; i < nr_bhs; i++)
brelse(bhs[i]);
@@ -549,11 +563,6 @@ int fat_free_clusters(struct inode *inod
}
if (nr_bhs + fatent.nr_bhs > MAX_BUF_PER_PAGE) {
- if (sb->s_flags & MS_SYNCHRONOUS) {
- err = fat_sync_bhs(bhs, nr_bhs);
- if (err)
- goto error;
- }
err = fat_mirror_bhs(sb, bhs, nr_bhs);
if (err)
goto error;
@@ -564,11 +573,6 @@ int fat_free_clusters(struct inode *inod
fat_collect_bhs(bhs, &nr_bhs, &fatent);
} while (cluster != FAT_ENT_EOF);
- if (sb->s_flags & MS_SYNCHRONOUS) {
- err = fat_sync_bhs(bhs, nr_bhs);
- if (err)
- goto error;
- }
err = fat_mirror_bhs(sb, bhs, nr_bhs);
error:
fatent_brelse(&fatent);
--- a/fs/fat/misc.c 2006-09-19 23:42:06.000000000 -0400
+++ b/fs/fat/misc.c 2006-10-31 09:08:01.000000000 -0500
@@ -194,19 +194,28 @@ void fat_date_unix2dos(int unix_date, __
EXPORT_SYMBOL_GPL(fat_date_unix2dos);
-int fat_sync_bhs(struct buffer_head **bhs, int nr_bhs)
+
+
+int fat_sync_bhs_optw(struct buffer_head **bhs, int nr_bhs ,int wait)
{
int i, err = 0;
ll_rw_block(SWRITE, nr_bhs, bhs);
- for (i = 0; i < nr_bhs; i++) {
- wait_on_buffer(bhs[i]);
- if (buffer_eopnotsupp(bhs[i])) {
- clear_buffer_eopnotsupp(bhs[i]);
- err = -EOPNOTSUPP;
- } else if (!err && !buffer_uptodate(bhs[i]))
- err = -EIO;
+ if (wait) {
+ for (i = 0; i < nr_bhs; i++) {
+ wait_on_buffer(bhs[i]);
+ if (buffer_eopnotsupp(bhs[i])) {
+ clear_buffer_eopnotsupp(bhs[i]);
+ err = -EOPNOTSUPP;
+ } else if (!err && !buffer_uptodate(bhs[i]))
+ err = -EIO;
+ }
}
+
return err;
}
+inline int fat_sync_bhs(struct buffer_head **bhs, int nr_bhs ) {
+ return fat_sync_bhs_optw(bhs , nr_bhs , 1);
+}
+
--- a/include/linux/msdos_fs.h 2006-09-19 23:42:06.000000000 -0400
+++ b/include/linux/msdos_fs.h 2006-10-25 18:53:50.000000000 -0400
@@ -419,6 +419,7 @@ extern int fat_chain_add(struct inode *i
extern int date_dos2unix(unsigned short time, unsigned short date);
extern void fat_date_unix2dos(int unix_date, __le16 *time, __le16 *date);
extern int fat_sync_bhs(struct buffer_head **bhs, int nr_bhs);
+extern int fat_sync_bhs_optw(struct buffer_head **bhs, int nr_bhs, int wait);
int fat_cache_init(void);
void fat_cache_destroy(void);
next reply other threads:[~2006-10-31 15:08 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-10-31 15:03 Holden Karau [this message]
2006-10-31 16:28 ` [PATCH 1/1] fat: improve sync performance by grouping writes revised Matthew Wilcox
2006-10-31 16:46 ` Holden Karau
2006-11-01 3:10 ` Holden Karau
2006-11-01 13:50 ` Matthew Wilcox
2006-10-31 16:30 ` Jörn Engel
2006-10-31 16:30 ` Jörn Engel
2006-10-31 18:10 ` Holden Karau
2006-10-31 18:10 ` Holden Karau
2006-10-31 16:54 ` OGAWA Hirofumi
2006-10-31 18:46 ` Holden Karau
2006-10-31 20:23 ` OGAWA Hirofumi
2006-10-31 20:54 ` Holden Karau
2006-11-01 0:58 ` OGAWA Hirofumi
2006-11-01 2:33 ` Holden Karau
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=454765AC.1050905@xandros.com \
--to=holdenk@xandros.com \
--cc=akpm@osdl.org \
--cc=hirofumi@mail.parknet.co.jp \
--cc=holden.karau@gmail.com \
--cc=holden@pigscanfly.ca \
--cc=joern@wohnheim.fh-wedel.de \
--cc=jsipek@fsl.cs.sunysb.edu \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=nickpiggin@yahoo.com.au \
/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.