All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 2/2] fat: optimize fat_count_free_clusters()
@ 2007-11-04 22:09 OGAWA Hirofumi
  2007-11-06  0:49 ` Andrew Morton
  0 siblings, 1 reply; 3+ messages in thread
From: OGAWA Hirofumi @ 2007-11-04 22:09 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-kernel

On large partition, scanning the free clusters is very slow if users
doesn't use "usefree" option.

For optimizing it, this patch uses sb_breadahead() to read of FAT
sectors. On some user's 15GB partition, this patch improved it very
much (1min => 600ms).

The following is the result of 2GB partition on my machine.

without patch:
	root@devron (/)# time df -h > /dev/null

	real    0m1.202s
	user    0m0.000s
	sys     0m0.440s

with patch:
	root@devron (/)# time df -h > /dev/null

	real    0m0.378s
	user    0m0.012s
	sys     0m0.168s

Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
---

 fs/fat/fatent.c |   28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff -puN fs/fat/fatent.c~fat_optimize-count-freeclus fs/fat/fatent.c
--- linux-2.6/fs/fat/fatent.c~fat_optimize-count-freeclus	2007-11-05 06:01:10.000000000 +0900
+++ linux-2.6-hirofumi/fs/fat/fatent.c	2007-11-05 06:01:10.000000000 +0900
@@ -590,21 +590,49 @@ error:
 
 EXPORT_SYMBOL_GPL(fat_free_clusters);
 
+/* 128kb is the whole sectors for FAT12 and FAT16 */
+#define FAT_READA_SIZE		(128 * 1024)
+
+static void fat_ent_reada(struct super_block *sb, struct fat_entry *fatent,
+			  unsigned long reada_blocks)
+{
+	struct fatent_operations *ops = MSDOS_SB(sb)->fatent_ops;
+	sector_t blocknr;
+	int i, offset;
+
+	ops->ent_blocknr(sb, fatent->entry, &offset, &blocknr);
+
+	for (i = 0; i < reada_blocks; i++)
+		sb_breadahead(sb, blocknr + i);
+}
+
 int fat_count_free_clusters(struct super_block *sb)
 {
 	struct msdos_sb_info *sbi = MSDOS_SB(sb);
 	struct fatent_operations *ops = sbi->fatent_ops;
 	struct fat_entry fatent;
+	unsigned long reada_blocks, reada_mask, cur_block;
 	int err = 0, free;
 
 	lock_fat(sbi);
 	if (sbi->free_clusters != -1)
 		goto out;
 
+	reada_blocks = FAT_READA_SIZE >> sb->s_blocksize_bits;
+	reada_mask = reada_blocks - 1;
+	cur_block = 0;
+
 	free = 0;
 	fatent_init(&fatent);
 	fatent_set_entry(&fatent, FAT_START_ENT);
 	while (fatent.entry < sbi->max_cluster) {
+		/* readahead of fat blocks */
+		if ((cur_block & reada_mask) == 0) {
+			unsigned long rest = sbi->fat_length - cur_block;
+			fat_ent_reada(sb, &fatent, min(reada_blocks, rest));
+		}
+		cur_block++;
+
 		err = fat_ent_read_block(sb, &fatent);
 		if (err)
 			goto out;
_

-- 
OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH 2/2] fat: optimize fat_count_free_clusters()
  2007-11-04 22:09 [PATCH 2/2] fat: optimize fat_count_free_clusters() OGAWA Hirofumi
@ 2007-11-06  0:49 ` Andrew Morton
  2007-11-06  2:07   ` OGAWA Hirofumi
  0 siblings, 1 reply; 3+ messages in thread
From: Andrew Morton @ 2007-11-06  0:49 UTC (permalink / raw)
  To: OGAWA Hirofumi; +Cc: linux-kernel

On Mon, 05 Nov 2007 07:09:00 +0900
OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> wrote:

> On large partition, scanning the free clusters is very slow if users
> doesn't use "usefree" option.
> 
> For optimizing it, this patch uses sb_breadahead() to read of FAT
> sectors. On some user's 15GB partition, this patch improved it very
> much (1min => 600ms).
> 
> The following is the result of 2GB partition on my machine.
> 
> without patch:
> 	root@devron (/)# time df -h > /dev/null
> 
> 	real    0m1.202s
> 	user    0m0.000s
> 	sys     0m0.440s
> 
> with patch:
> 	root@devron (/)# time df -h > /dev/null
> 
> 	real    0m0.378s
> 	user    0m0.012s
> 	sys     0m0.168s
> 

Can't complain about that ;)

> ---
> 
>  fs/fat/fatent.c |   28 ++++++++++++++++++++++++++++
>  1 file changed, 28 insertions(+)
> 
> diff -puN fs/fat/fatent.c~fat_optimize-count-freeclus fs/fat/fatent.c
> --- linux-2.6/fs/fat/fatent.c~fat_optimize-count-freeclus	2007-11-05 06:01:10.000000000 +0900
> +++ linux-2.6-hirofumi/fs/fat/fatent.c	2007-11-05 06:01:10.000000000 +0900
> @@ -590,21 +590,49 @@ error:
>  
>  EXPORT_SYMBOL_GPL(fat_free_clusters);
>  
> +/* 128kb is the whole sectors for FAT12 and FAT16 */
> +#define FAT_READA_SIZE		(128 * 1024)
> +
> +static void fat_ent_reada(struct super_block *sb, struct fat_entry *fatent,
> +			  unsigned long reada_blocks)
> +{
> +	struct fatent_operations *ops = MSDOS_SB(sb)->fatent_ops;
> +	sector_t blocknr;
> +	int i, offset;
> +
> +	ops->ent_blocknr(sb, fatent->entry, &offset, &blocknr);
> +
> +	for (i = 0; i < reada_blocks; i++)
> +		sb_breadahead(sb, blocknr + i);
> +}

You might find that it's simpler and faster to call
page_cache_sync_readahead() against sb->s_bdev->bd_inode->i_mapping.

Or maybe not - that requires a struct file_ra_state.  We _used_ to have a
nice simple read-some-stuff-into-pagecache function which didn't need an
ra_state but that seems to have disappeared in the various recent readahead
churn.  Oh well.


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH 2/2] fat: optimize fat_count_free_clusters()
  2007-11-06  0:49 ` Andrew Morton
@ 2007-11-06  2:07   ` OGAWA Hirofumi
  0 siblings, 0 replies; 3+ messages in thread
From: OGAWA Hirofumi @ 2007-11-06  2:07 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-kernel

Andrew Morton <akpm@linux-foundation.org> writes:

>> +/* 128kb is the whole sectors for FAT12 and FAT16 */
>> +#define FAT_READA_SIZE		(128 * 1024)
>> +
>> +static void fat_ent_reada(struct super_block *sb, struct fat_entry *fatent,
>> +			  unsigned long reada_blocks)
>> +{
>> +	struct fatent_operations *ops = MSDOS_SB(sb)->fatent_ops;
>> +	sector_t blocknr;
>> +	int i, offset;
>> +
>> +	ops->ent_blocknr(sb, fatent->entry, &offset, &blocknr);
>> +
>> +	for (i = 0; i < reada_blocks; i++)
>> +		sb_breadahead(sb, blocknr + i);
>> +}
>
> You might find that it's simpler and faster to call
> page_cache_sync_readahead() against sb->s_bdev->bd_inode->i_mapping.
>
> Or maybe not - that requires a struct file_ra_state.  We _used_ to have a
> nice simple read-some-stuff-into-pagecache function which didn't need an
> ra_state but that seems to have disappeared in the various recent readahead
> churn.  Oh well.

Yes. I found it, but I gave up for now by file_ra_state. Also I'd like
to use a large block to read FAT.  I'll rethink this code after large
block was merged.

Thanks.
-- 
OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2007-11-06  2:07 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-11-04 22:09 [PATCH 2/2] fat: optimize fat_count_free_clusters() OGAWA Hirofumi
2007-11-06  0:49 ` Andrew Morton
2007-11-06  2:07   ` OGAWA Hirofumi

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.