* [PATCH] ext4: fix free clusters calculation in bigalloc filesystem
@ 2013-02-21 8:01 Lukas Czerner
2013-02-21 12:15 ` [PATCH] ext4: fix overhead calculation in bigalloc filesystem (Re: ... ) Zheng Liu
` (2 more replies)
0 siblings, 3 replies; 19+ messages in thread
From: Lukas Czerner @ 2013-02-21 8:01 UTC (permalink / raw)
To: linux-ext4; +Cc: Lukas Czerner
ext4_has_free_clusters() should tell us whether there is enough free
clusters to allocate, however number of free clusters in the file system
is converted to blocks using EXT4_C2B() which is not only wrong use of
the macro (we should have used EXT4_NUM_B2C) but it's also completely
wrong concept since everything else is in cluster units.
Moreover when calculating number of root clusters we should be using
macro EXT4_NUM_B2C() instead of EXT4_C2B() otherwise the result will
usually be off by one.
As a result number of free clusters is much bigger than it should have
been and ext4_has_free_clusters() would return 1 even if there is really
not enough free clusters available.
Fix this by removing the EXT4_C2B() conversion of free clusters and
using EXT4_NUM_B2C() when calculating number of root clusters. This bug
affects number of xfstests tests covering file system ENOSPC situation
handling. With this patch most of the ENOSPC problems with bigalloc file
system disappear, especially the errors caused by delayed allocation not
having enough space when the actual allocation is finally requested.
Signed-off-by: Lukas Czerner <lczerner@redhat.com>
---
fs/ext4/balloc.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
index cf18217..9f4302a 100644
--- a/fs/ext4/balloc.c
+++ b/fs/ext4/balloc.c
@@ -482,11 +482,11 @@ static int ext4_has_free_clusters(struct ext4_sb_info *sbi,
free_clusters = percpu_counter_read_positive(fcc);
dirty_clusters = percpu_counter_read_positive(dcc);
- root_clusters = EXT4_B2C(sbi, ext4_r_blocks_count(sbi->s_es));
+ root_clusters = EXT4_NUM_B2C(sbi, ext4_r_blocks_count(sbi->s_es));
if (free_clusters - (nclusters + root_clusters + dirty_clusters) <
EXT4_FREECLUSTERS_WATERMARK) {
- free_clusters = EXT4_C2B(sbi, percpu_counter_sum_positive(fcc));
+ free_clusters = percpu_counter_sum_positive(fcc);
dirty_clusters = percpu_counter_sum_positive(dcc);
}
/* Check whether we have space after accounting for current
--
1.7.7.6
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH] ext4: fix overhead calculation in bigalloc filesystem (Re: ... )
2013-02-21 8:01 [PATCH] ext4: fix free clusters calculation in bigalloc filesystem Lukas Czerner
@ 2013-02-21 12:15 ` Zheng Liu
2013-02-21 12:40 ` Lukáš Czerner
2013-02-22 5:10 ` [PATCH] ext4: fix free clusters calculation in bigalloc filesystem Theodore Ts'o
2013-02-22 8:39 ` [PATCH v2] " Lukas Czerner
2 siblings, 1 reply; 19+ messages in thread
From: Zheng Liu @ 2013-02-21 12:15 UTC (permalink / raw)
To: Lukas Czerner; +Cc: linux-ext4, Theodore Ts'o
On Thu, Feb 21, 2013 at 09:01:05AM +0100, Lukas Czerner wrote:
> ext4_has_free_clusters() should tell us whether there is enough free
> clusters to allocate, however number of free clusters in the file system
> is converted to blocks using EXT4_C2B() which is not only wrong use of
> the macro (we should have used EXT4_NUM_B2C) but it's also completely
> wrong concept since everything else is in cluster units.
>
> Moreover when calculating number of root clusters we should be using
> macro EXT4_NUM_B2C() instead of EXT4_C2B() otherwise the result will
> usually be off by one.
>
> As a result number of free clusters is much bigger than it should have
> been and ext4_has_free_clusters() would return 1 even if there is really
> not enough free clusters available.
>
> Fix this by removing the EXT4_C2B() conversion of free clusters and
> using EXT4_NUM_B2C() when calculating number of root clusters. This bug
> affects number of xfstests tests covering file system ENOSPC situation
> handling. With this patch most of the ENOSPC problems with bigalloc file
> system disappear, especially the errors caused by delayed allocation not
> having enough space when the actual allocation is finally requested.
>
> Signed-off-by: Lukas Czerner <lczerner@redhat.com>
Great! Thanks for fixing it. After applied this patch, xfstests #15
with bigalloc and delalloc won't cause a failure. You can add
Reviewed-and-tested-by: Zheng Liu <wenqing.lz@taobao.com>
BTW, xfstests (204, 219, 233, 235, 273, and 274) still cause failures in
my test environment, and I still get a warning message which looks like:
kernel: EXT4-fs (sda2): ext4_da_update_reserve_space: ino 3658, allocated 1
with only 0 reserved metadata blocks
kernel:
kernel: ------------[ cut here ]------------
kernel: WARNING: at fs/ext4/inode.c:362 ext4_da_update_reserve_space+0x10f/0x21b
[ext4]()
kernel: Hardware name: OptiPlex 780
kernel: Modules linked in: ext4 jbd2 crc16 cpufreq_ondemand ipv6 dm_mirror
dm_region_hash dm_log dm_mod parport_pc parport cspkr i2c_i801 i2c_core
serio_raw sg ehci_pci ehci_hcd button e1000e ext3 jbd sd_mod ahci libahci libata
scsi_mod uhci_hcd
kernel: Pid: 2628, comm: 2372.fsstress.b Tainted: G W 3.8.0+ #7
kernel: Call Trace:
kernel: [<ffffffff82031d68>] warn_slowpath_common+0x85/0x9d
kernel: [<ffffffff82031d9a>] warn_slowpath_null+0x1a/0x1c
kernel: [<ffffffffa0200240>] ext4_da_update_reserve_space+0x10f/0x21b [ext4]
kernel: [<ffffffffa02277cd>] ext4_ext_map_blocks+0xd83/0xf66 [ext4]
kernel: [<ffffffff820ba4a8>] ? release_pages+0x169/0x178
kernel: [<ffffffff820ba011>] ? pagevec_lookup_tag+0x25/0x2e
kernel: [<ffffffffa02018d3>] ? write_cache_pages_da+0x107/0x3c4 [ext4]
kernel: [<ffffffffa0200c36>] ext4_map_blocks+0x135/0x1ef [ext4]
kernel: [<ffffffffa0201451>] mpage_da_map_and_submit+0x111/0x3d8 [ext4]
kernel: [<ffffffffa0201f0e>] ext4_da_writepages+0x37e/0x526 [ext4]
kernel: [<ffffffff820b86d9>] do_writepages+0x20/0x29
kernel: [<ffffffff820b13da>] __filemap_fdatawrite_range+0x50/0x52
kernel: [<ffffffff820b19a5>] filemap_fdatawrite+0x1f/0x21
kernel: [<ffffffff820b19c4>] filemap_write_and_wait+0x1d/0x38
kernel: [<ffffffff820fc4a9>] do_vfs_ioctl+0x2db/0x47f
kernel: [<ffffffff820fc6ab>] sys_ioctl+0x5e/0x82
kernel: [<ffffffff82386942>] system_call_fastpath+0x16/0x1b
kernel: ---[ end trace d96610456f905628 ]---
It is easy to trigger this warning when running xfstests #127 or #225.
Moreover, it seems that there still has an improvement in
ext4_calculate_overhead(). I paste the patch here.
Regards,
- Zheng
Subject: [PATCH] ext4: fix overhead calculation in bigalloc filesystem
From: Zheng Liu <wenqing.lz@taobao.com>
ext4_calculate_overhead() should compute the overhead and stash it in
sbi->s_overhead. But we miss use EXT4_B2C() to calculate the number of
clusters before first_data_block and the number of journal blocks. This
commit use EXT4_NUM_B2C() instead of EXT4_B2C() to calculate the
overhead.
Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
Cc: "Theodore Ts'o" <tytso@mit.edu>
---
fs/ext4/super.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 3d4fb81..6165558 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -3219,7 +3219,7 @@ int ext4_calculate_overhead(struct super_block *sb)
/*
* All of the blocks before first_data_block are overhead
*/
- overhead = EXT4_B2C(sbi, le32_to_cpu(es->s_first_data_block));
+ overhead = EXT4_NUM_B2C(sbi, le32_to_cpu(es->s_first_data_block));
/*
* Add the overhead found in each block group
@@ -3235,7 +3235,7 @@ int ext4_calculate_overhead(struct super_block *sb)
}
/* Add the journal blocks as well */
if (sbi->s_journal)
- overhead += EXT4_B2C(sbi, sbi->s_journal->j_maxlen);
+ overhead += EXT4_NUM_B2C(sbi, sbi->s_journal->j_maxlen);
sbi->s_overhead = overhead;
smp_wmb();
--
1.7.12.rc2.18.g61b472e
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH] ext4: fix overhead calculation in bigalloc filesystem (Re: ... )
2013-02-21 12:15 ` [PATCH] ext4: fix overhead calculation in bigalloc filesystem (Re: ... ) Zheng Liu
@ 2013-02-21 12:40 ` Lukáš Czerner
2013-02-21 12:50 ` Lukáš Czerner
2013-02-21 13:12 ` [PATCH] ext4: fix overhead calculation in bigalloc filesystem (Re: ... ) Zheng Liu
0 siblings, 2 replies; 19+ messages in thread
From: Lukáš Czerner @ 2013-02-21 12:40 UTC (permalink / raw)
To: Zheng Liu; +Cc: Lukas Czerner, linux-ext4, Theodore Ts'o
On Thu, 21 Feb 2013, Zheng Liu wrote:
> Date: Thu, 21 Feb 2013 20:15:45 +0800
> From: Zheng Liu <gnehzuil.liu@gmail.com>
> To: Lukas Czerner <lczerner@redhat.com>
> Cc: linux-ext4@vger.kernel.org, Theodore Ts'o <tytso@mit.edu>
> Subject: [PATCH] ext4: fix overhead calculation in bigalloc filesystem (Re:
> ... )
>
> On Thu, Feb 21, 2013 at 09:01:05AM +0100, Lukas Czerner wrote:
> > ext4_has_free_clusters() should tell us whether there is enough free
> > clusters to allocate, however number of free clusters in the file system
> > is converted to blocks using EXT4_C2B() which is not only wrong use of
> > the macro (we should have used EXT4_NUM_B2C) but it's also completely
> > wrong concept since everything else is in cluster units.
> >
> > Moreover when calculating number of root clusters we should be using
> > macro EXT4_NUM_B2C() instead of EXT4_C2B() otherwise the result will
> > usually be off by one.
> >
> > As a result number of free clusters is much bigger than it should have
> > been and ext4_has_free_clusters() would return 1 even if there is really
> > not enough free clusters available.
> >
> > Fix this by removing the EXT4_C2B() conversion of free clusters and
> > using EXT4_NUM_B2C() when calculating number of root clusters. This bug
> > affects number of xfstests tests covering file system ENOSPC situation
> > handling. With this patch most of the ENOSPC problems with bigalloc file
> > system disappear, especially the errors caused by delayed allocation not
> > having enough space when the actual allocation is finally requested.
> >
> > Signed-off-by: Lukas Czerner <lczerner@redhat.com>
>
> Great! Thanks for fixing it. After applied this patch, xfstests #15
> with bigalloc and delalloc won't cause a failure. You can add
> Reviewed-and-tested-by: Zheng Liu <wenqing.lz@taobao.com>
>
> BTW, xfstests (204, 219, 233, 235, 273, and 274) still cause failures in
> my test environment, and I still get a warning message which looks like:
>
> kernel: EXT4-fs (sda2): ext4_da_update_reserve_space: ino 3658, allocated 1
> with only 0 reserved metadata blocks
> kernel:
> kernel: ------------[ cut here ]------------
> kernel: WARNING: at fs/ext4/inode.c:362 ext4_da_update_reserve_space+0x10f/0x21b
> [ext4]()
> kernel: Hardware name: OptiPlex 780
> kernel: Modules linked in: ext4 jbd2 crc16 cpufreq_ondemand ipv6 dm_mirror
> dm_region_hash dm_log dm_mod parport_pc parport cspkr i2c_i801 i2c_core
> serio_raw sg ehci_pci ehci_hcd button e1000e ext3 jbd sd_mod ahci libahci libata
> scsi_mod uhci_hcd
> kernel: Pid: 2628, comm: 2372.fsstress.b Tainted: G W 3.8.0+ #7
> kernel: Call Trace:
> kernel: [<ffffffff82031d68>] warn_slowpath_common+0x85/0x9d
> kernel: [<ffffffff82031d9a>] warn_slowpath_null+0x1a/0x1c
> kernel: [<ffffffffa0200240>] ext4_da_update_reserve_space+0x10f/0x21b [ext4]
> kernel: [<ffffffffa02277cd>] ext4_ext_map_blocks+0xd83/0xf66 [ext4]
> kernel: [<ffffffff820ba4a8>] ? release_pages+0x169/0x178
> kernel: [<ffffffff820ba011>] ? pagevec_lookup_tag+0x25/0x2e
> kernel: [<ffffffffa02018d3>] ? write_cache_pages_da+0x107/0x3c4 [ext4]
> kernel: [<ffffffffa0200c36>] ext4_map_blocks+0x135/0x1ef [ext4]
> kernel: [<ffffffffa0201451>] mpage_da_map_and_submit+0x111/0x3d8 [ext4]
> kernel: [<ffffffffa0201f0e>] ext4_da_writepages+0x37e/0x526 [ext4]
> kernel: [<ffffffff820b86d9>] do_writepages+0x20/0x29
> kernel: [<ffffffff820b13da>] __filemap_fdatawrite_range+0x50/0x52
> kernel: [<ffffffff820b19a5>] filemap_fdatawrite+0x1f/0x21
> kernel: [<ffffffff820b19c4>] filemap_write_and_wait+0x1d/0x38
> kernel: [<ffffffff820fc4a9>] do_vfs_ioctl+0x2db/0x47f
> kernel: [<ffffffff820fc6ab>] sys_ioctl+0x5e/0x82
> kernel: [<ffffffff82386942>] system_call_fastpath+0x16/0x1b
> kernel: ---[ end trace d96610456f905628 ]---
>
> It is easy to trigger this warning when running xfstests #127 or #225.
>
> Moreover, it seems that there still has an improvement in
> ext4_calculate_overhead(). I paste the patch here.
>
> Regards,
> - Zheng
Hi Zheng,
thanks for the review. I know about the other issues and I'm trying
to resolve those as well. Right now I have a patch which includes
the changes ext4_calculate_overhead() you've described below and more,
but even with this I still see some problems remaining.
Hopefully will send another patch soon.
Thanks!
-Lukas
>
> Subject: [PATCH] ext4: fix overhead calculation in bigalloc filesystem
>
> From: Zheng Liu <wenqing.lz@taobao.com>
>
> ext4_calculate_overhead() should compute the overhead and stash it in
> sbi->s_overhead. But we miss use EXT4_B2C() to calculate the number of
> clusters before first_data_block and the number of journal blocks. This
> commit use EXT4_NUM_B2C() instead of EXT4_B2C() to calculate the
> overhead.
>
> Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
> Cc: "Theodore Ts'o" <tytso@mit.edu>
> ---
> fs/ext4/super.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/fs/ext4/super.c b/fs/ext4/super.c
> index 3d4fb81..6165558 100644
> --- a/fs/ext4/super.c
> +++ b/fs/ext4/super.c
> @@ -3219,7 +3219,7 @@ int ext4_calculate_overhead(struct super_block *sb)
> /*
> * All of the blocks before first_data_block are overhead
> */
> - overhead = EXT4_B2C(sbi, le32_to_cpu(es->s_first_data_block));
> + overhead = EXT4_NUM_B2C(sbi, le32_to_cpu(es->s_first_data_block));
>
> /*
> * Add the overhead found in each block group
> @@ -3235,7 +3235,7 @@ int ext4_calculate_overhead(struct super_block *sb)
> }
> /* Add the journal blocks as well */
> if (sbi->s_journal)
> - overhead += EXT4_B2C(sbi, sbi->s_journal->j_maxlen);
> + overhead += EXT4_NUM_B2C(sbi, sbi->s_journal->j_maxlen);
>
> sbi->s_overhead = overhead;
> smp_wmb();
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] ext4: fix overhead calculation in bigalloc filesystem (Re: ... )
2013-02-21 12:40 ` Lukáš Czerner
@ 2013-02-21 12:50 ` Lukáš Czerner
2013-02-21 12:52 ` Lukáš Czerner
2013-02-21 13:12 ` [PATCH] ext4: fix overhead calculation in bigalloc filesystem (Re: ... ) Zheng Liu
1 sibling, 1 reply; 19+ messages in thread
From: Lukáš Czerner @ 2013-02-21 12:50 UTC (permalink / raw)
To: Lukáš Czerner; +Cc: Zheng Liu, linux-ext4, Theodore Ts'o
[-- Attachment #1: Type: TEXT/PLAIN, Size: 2244 bytes --]
On Thu, 21 Feb 2013, Lukáš Czerner wrote:
..snip...
>
> Hi Zheng,
>
> thanks for the review. I know about the other issues and I'm trying
> to resolve those as well. Right now I have a patch which includes
> the changes ext4_calculate_overhead() you've described below and more,
> but even with this I still see some problems remaining.
>
> Hopefully will send another patch soon.
>
> Thanks!
> -Lukas
>
> >
> > Subject: [PATCH] ext4: fix overhead calculation in bigalloc filesystem
> >
> > From: Zheng Liu <wenqing.lz@taobao.com>
> >
> > ext4_calculate_overhead() should compute the overhead and stash it in
> > sbi->s_overhead. But we miss use EXT4_B2C() to calculate the number of
> > clusters before first_data_block and the number of journal blocks. This
> > commit use EXT4_NUM_B2C() instead of EXT4_B2C() to calculate the
> > overhead.
> >
> > Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
> > Cc: "Theodore Ts'o" <tytso@mit.edu>
> > ---
> > fs/ext4/super.c | 4 ++--
> > 1 file changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/fs/ext4/super.c b/fs/ext4/super.c
> > index 3d4fb81..6165558 100644
> > --- a/fs/ext4/super.c
> > +++ b/fs/ext4/super.c
> > @@ -3219,7 +3219,7 @@ int ext4_calculate_overhead(struct super_block *sb)
> > /*
> > * All of the blocks before first_data_block are overhead
> > */
> > - overhead = EXT4_B2C(sbi, le32_to_cpu(es->s_first_data_block));
> > + overhead = EXT4_NUM_B2C(sbi, le32_to_cpu(es->s_first_data_block));
...except this. I do not think this is right because we do not skip
the first cluster right ? We're still using it, but we can never use
the block before es->s_first_data_block. Please correct me if I am
wrong.
> >
> > /*
> > * Add the overhead found in each block group
> > @@ -3235,7 +3235,7 @@ int ext4_calculate_overhead(struct super_block *sb)
> > }
> > /* Add the journal blocks as well */
> > if (sbi->s_journal)
> > - overhead += EXT4_B2C(sbi, sbi->s_journal->j_maxlen);
> > + overhead += EXT4_NUM_B2C(sbi, sbi->s_journal->j_maxlen);
This I already have in my patch I'm testing right now. And as I said
there are other places where we misuse EXT4_B2C().
-Lukas
> >
> > sbi->s_overhead = overhead;
> > smp_wmb();
> >
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] ext4: fix overhead calculation in bigalloc filesystem (Re: ... )
2013-02-21 12:50 ` Lukáš Czerner
@ 2013-02-21 12:52 ` Lukáš Czerner
2013-02-21 13:49 ` Zheng Liu
0 siblings, 1 reply; 19+ messages in thread
From: Lukáš Czerner @ 2013-02-21 12:52 UTC (permalink / raw)
To: Lukáš Czerner; +Cc: Zheng Liu, linux-ext4, Theodore Ts'o
[-- Attachment #1: Type: TEXT/PLAIN, Size: 2836 bytes --]
On Thu, 21 Feb 2013, Lukáš Czerner wrote:
> Date: Thu, 21 Feb 2013 13:50:03 +0100 (CET)
> From: Lukáš Czerner <lczerner@redhat.com>
> To: Lukáš Czerner <lczerner@redhat.com>
> Cc: Zheng Liu <gnehzuil.liu@gmail.com>, linux-ext4@vger.kernel.org,
> Theodore Ts'o <tytso@mit.edu>
> Subject: Re: [PATCH] ext4: fix overhead calculation in bigalloc filesystem
> (Re: ... )
>
> On Thu, 21 Feb 2013, Lukáš Czerner wrote:
>
> ..snip...
>
> >
> > Hi Zheng,
> >
> > thanks for the review. I know about the other issues and I'm trying
> > to resolve those as well. Right now I have a patch which includes
> > the changes ext4_calculate_overhead() you've described below and more,
> > but even with this I still see some problems remaining.
> >
> > Hopefully will send another patch soon.
> >
> > Thanks!
> > -Lukas
> >
> > >
> > > Subject: [PATCH] ext4: fix overhead calculation in bigalloc filesystem
> > >
> > > From: Zheng Liu <wenqing.lz@taobao.com>
> > >
> > > ext4_calculate_overhead() should compute the overhead and stash it in
> > > sbi->s_overhead. But we miss use EXT4_B2C() to calculate the number of
> > > clusters before first_data_block and the number of journal blocks. This
> > > commit use EXT4_NUM_B2C() instead of EXT4_B2C() to calculate the
> > > overhead.
> > >
> > > Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
> > > Cc: "Theodore Ts'o" <tytso@mit.edu>
> > > ---
> > > fs/ext4/super.c | 4 ++--
> > > 1 file changed, 2 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/fs/ext4/super.c b/fs/ext4/super.c
> > > index 3d4fb81..6165558 100644
> > > --- a/fs/ext4/super.c
> > > +++ b/fs/ext4/super.c
> > > @@ -3219,7 +3219,7 @@ int ext4_calculate_overhead(struct super_block *sb)
> > > /*
> > > * All of the blocks before first_data_block are overhead
> > > */
> > > - overhead = EXT4_B2C(sbi, le32_to_cpu(es->s_first_data_block));
> > > + overhead = EXT4_NUM_B2C(sbi, le32_to_cpu(es->s_first_data_block));
>
> ...except this. I do not think this is right because we do not skip
> the first cluster right ? We're still using it, but we can never use
> the block before es->s_first_data_block. Please correct me if I am
> wrong.
moreover we do not allow bigalloc file system with block size < 4k.
>
>
> > >
> > > /*
> > > * Add the overhead found in each block group
> > > @@ -3235,7 +3235,7 @@ int ext4_calculate_overhead(struct super_block *sb)
> > > }
> > > /* Add the journal blocks as well */
> > > if (sbi->s_journal)
> > > - overhead += EXT4_B2C(sbi, sbi->s_journal->j_maxlen);
> > > + overhead += EXT4_NUM_B2C(sbi, sbi->s_journal->j_maxlen);
>
> This I already have in my patch I'm testing right now. And as I said
> there are other places where we misuse EXT4_B2C().
>
> -Lukas
>
> > >
> > > sbi->s_overhead = overhead;
> > > smp_wmb();
> > >
> >
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] ext4: fix overhead calculation in bigalloc filesystem (Re: ... )
2013-02-21 12:40 ` Lukáš Czerner
2013-02-21 12:50 ` Lukáš Czerner
@ 2013-02-21 13:12 ` Zheng Liu
1 sibling, 0 replies; 19+ messages in thread
From: Zheng Liu @ 2013-02-21 13:12 UTC (permalink / raw)
To: Lukáš Czerner; +Cc: linux-ext4, Theodore Ts'o
On Thu, Feb 21, 2013 at 01:40:34PM +0100, Lukáš Czerner wrote:
[snip]
>
> Hi Zheng,
>
> thanks for the review. I know about the other issues and I'm trying
> to resolve those as well. Right now I have a patch which includes
> the changes ext4_calculate_overhead() you've described below and more,
> but even with this I still see some problems remaining.
>
> Hopefully will send another patch soon.
Yeah, we will get a lot of xfstests failures about bigalloc feature when
bigalloc and delalloc are enabled simultaneouly. So that would be great
if we could fix these problems. Looking forward your patch. :-)
Regards,
- Zheng
> >
> > Subject: [PATCH] ext4: fix overhead calculation in bigalloc filesystem
> >
> > From: Zheng Liu <wenqing.lz@taobao.com>
> >
> > ext4_calculate_overhead() should compute the overhead and stash it in
> > sbi->s_overhead. But we miss use EXT4_B2C() to calculate the number of
> > clusters before first_data_block and the number of journal blocks. This
> > commit use EXT4_NUM_B2C() instead of EXT4_B2C() to calculate the
> > overhead.
> >
> > Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
> > Cc: "Theodore Ts'o" <tytso@mit.edu>
> > ---
> > fs/ext4/super.c | 4 ++--
> > 1 file changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/fs/ext4/super.c b/fs/ext4/super.c
> > index 3d4fb81..6165558 100644
> > --- a/fs/ext4/super.c
> > +++ b/fs/ext4/super.c
> > @@ -3219,7 +3219,7 @@ int ext4_calculate_overhead(struct super_block *sb)
> > /*
> > * All of the blocks before first_data_block are overhead
> > */
> > - overhead = EXT4_B2C(sbi, le32_to_cpu(es->s_first_data_block));
> > + overhead = EXT4_NUM_B2C(sbi, le32_to_cpu(es->s_first_data_block));
> >
> > /*
> > * Add the overhead found in each block group
> > @@ -3235,7 +3235,7 @@ int ext4_calculate_overhead(struct super_block *sb)
> > }
> > /* Add the journal blocks as well */
> > if (sbi->s_journal)
> > - overhead += EXT4_B2C(sbi, sbi->s_journal->j_maxlen);
> > + overhead += EXT4_NUM_B2C(sbi, sbi->s_journal->j_maxlen);
> >
> > sbi->s_overhead = overhead;
> > smp_wmb();
> >
--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] ext4: fix overhead calculation in bigalloc filesystem (Re: ... )
2013-02-21 12:52 ` Lukáš Czerner
@ 2013-02-21 13:49 ` Zheng Liu
2013-02-21 14:56 ` Lukáš Czerner
0 siblings, 1 reply; 19+ messages in thread
From: Zheng Liu @ 2013-02-21 13:49 UTC (permalink / raw)
To: Lukáš Czerner; +Cc: linux-ext4, Theodore Ts'o
On Thu, Feb 21, 2013 at 01:52:58PM +0100, Lukáš Czerner wrote:
> On Thu, 21 Feb 2013, Lukáš Czerner wrote:
>
> > Date: Thu, 21 Feb 2013 13:50:03 +0100 (CET)
> > From: Lukáš Czerner <lczerner@redhat.com>
> > To: Lukáš Czerner <lczerner@redhat.com>
> > Cc: Zheng Liu <gnehzuil.liu@gmail.com>, linux-ext4@vger.kernel.org,
> > Theodore Ts'o <tytso@mit.edu>
> > Subject: Re: [PATCH] ext4: fix overhead calculation in bigalloc filesystem
> > (Re: ... )
> >
> > On Thu, 21 Feb 2013, Lukáš Czerner wrote:
> >
> > ..snip...
> >
> > >
> > > Hi Zheng,
> > >
> > > thanks for the review. I know about the other issues and I'm trying
> > > to resolve those as well. Right now I have a patch which includes
> > > the changes ext4_calculate_overhead() you've described below and more,
> > > but even with this I still see some problems remaining.
> > >
> > > Hopefully will send another patch soon.
> > >
> > > Thanks!
> > > -Lukas
> > >
> > > >
> > > > Subject: [PATCH] ext4: fix overhead calculation in bigalloc filesystem
> > > >
> > > > From: Zheng Liu <wenqing.lz@taobao.com>
> > > >
> > > > ext4_calculate_overhead() should compute the overhead and stash it in
> > > > sbi->s_overhead. But we miss use EXT4_B2C() to calculate the number of
> > > > clusters before first_data_block and the number of journal blocks. This
> > > > commit use EXT4_NUM_B2C() instead of EXT4_B2C() to calculate the
> > > > overhead.
> > > >
> > > > Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
> > > > Cc: "Theodore Ts'o" <tytso@mit.edu>
> > > > ---
> > > > fs/ext4/super.c | 4 ++--
> > > > 1 file changed, 2 insertions(+), 2 deletions(-)
> > > >
> > > > diff --git a/fs/ext4/super.c b/fs/ext4/super.c
> > > > index 3d4fb81..6165558 100644
> > > > --- a/fs/ext4/super.c
> > > > +++ b/fs/ext4/super.c
> > > > @@ -3219,7 +3219,7 @@ int ext4_calculate_overhead(struct super_block *sb)
> > > > /*
> > > > * All of the blocks before first_data_block are overhead
> > > > */
> > > > - overhead = EXT4_B2C(sbi, le32_to_cpu(es->s_first_data_block));
> > > > + overhead = EXT4_NUM_B2C(sbi, le32_to_cpu(es->s_first_data_block));
> >
> > ...except this. I do not think this is right because we do not skip
> > the first cluster right ? We're still using it, but we can never use
> > the block before es->s_first_data_block. Please correct me if I am
> > wrong.
Yes, I think you are right.
>
> moreover we do not allow bigalloc file system with block size < 4k.
No, we allow user to use bigalloc with block size < 4k, such as:
mkfs.ext4 -b 1024 -C 4096 -O bigalloc ${dev}
This command formats a bigalloc filesystem with blocksize = 1k and
clustersize = 4k, at least in e2fsprogs 1.42.7 it works well.
>
> >
> >
> > > >
> > > > /*
> > > > * Add the overhead found in each block group
> > > > @@ -3235,7 +3235,7 @@ int ext4_calculate_overhead(struct super_block *sb)
> > > > }
> > > > /* Add the journal blocks as well */
> > > > if (sbi->s_journal)
> > > > - overhead += EXT4_B2C(sbi, sbi->s_journal->j_maxlen);
> > > > + overhead += EXT4_NUM_B2C(sbi, sbi->s_journal->j_maxlen);
> >
> > This I already have in my patch I'm testing right now. And as I said
> > there are other places where we misuse EXT4_B2C().
> >
> > -Lukas
> >
> > > >
> > > > sbi->s_overhead = overhead;
> > > > smp_wmb();
> > > >
> > >
> >
--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] ext4: fix overhead calculation in bigalloc filesystem (Re: ... )
2013-02-21 13:49 ` Zheng Liu
@ 2013-02-21 14:56 ` Lukáš Czerner
2013-02-22 3:03 ` Zheng Liu
0 siblings, 1 reply; 19+ messages in thread
From: Lukáš Czerner @ 2013-02-21 14:56 UTC (permalink / raw)
To: Zheng Liu; +Cc: Lukáš Czerner, linux-ext4, Theodore Ts'o
On Thu, 21 Feb 2013, Zheng Liu wrote:
..snip..
> > > > > /*
> > > > > * All of the blocks before first_data_block are overhead
> > > > > */
> > > > > - overhead = EXT4_B2C(sbi, le32_to_cpu(es->s_first_data_block));
> > > > > + overhead = EXT4_NUM_B2C(sbi, le32_to_cpu(es->s_first_data_block));
> > >
> > > ...except this. I do not think this is right because we do not skip
> > > the first cluster right ? We're still using it, but we can never use
> > > the block before es->s_first_data_block. Please correct me if I am
> > > wrong.
>
> Yes, I think you are right.
>
> >
> > moreover we do not allow bigalloc file system with block size < 4k.
>
> No, we allow user to use bigalloc with block size < 4k, such as:
>
> mkfs.ext4 -b 1024 -C 4096 -O bigalloc ${dev}
>
> This command formats a bigalloc filesystem with blocksize = 1k and
> clustersize = 4k, at least in e2fsprogs 1.42.7 it works well.
>
Ok, i was pretty sure that we do not allow that, it's good to know.
Also, does it make any sense ? I do not think so, and I would really
consider the fact that we allow that as a bug. We should not allow
that otherwise it unnecessarily extending the test matrix.
What people think about restricting bigalloc _only_ for 4k block
size file systems ?
Thanks!
-Lukas
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] ext4: fix overhead calculation in bigalloc filesystem (Re: ... )
2013-02-21 14:56 ` Lukáš Czerner
@ 2013-02-22 3:03 ` Zheng Liu
2013-02-22 4:05 ` Theodore Ts'o
0 siblings, 1 reply; 19+ messages in thread
From: Zheng Liu @ 2013-02-22 3:03 UTC (permalink / raw)
To: Lukáš Czerner; +Cc: linux-ext4, Theodore Ts'o
On Thu, Feb 21, 2013 at 03:56:51PM +0100, Lukáš Czerner wrote:
> On Thu, 21 Feb 2013, Zheng Liu wrote:
>
> ..snip..
>
> > > > > > /*
> > > > > > * All of the blocks before first_data_block are overhead
> > > > > > */
> > > > > > - overhead = EXT4_B2C(sbi, le32_to_cpu(es->s_first_data_block));
> > > > > > + overhead = EXT4_NUM_B2C(sbi, le32_to_cpu(es->s_first_data_block));
> > > >
> > > > ...except this. I do not think this is right because we do not skip
> > > > the first cluster right ? We're still using it, but we can never use
> > > > the block before es->s_first_data_block. Please correct me if I am
> > > > wrong.
> >
> > Yes, I think you are right.
> >
> > >
> > > moreover we do not allow bigalloc file system with block size < 4k.
> >
> > No, we allow user to use bigalloc with block size < 4k, such as:
> >
> > mkfs.ext4 -b 1024 -C 4096 -O bigalloc ${dev}
> >
> > This command formats a bigalloc filesystem with blocksize = 1k and
> > clustersize = 4k, at least in e2fsprogs 1.42.7 it works well.
> >
>
> Ok, i was pretty sure that we do not allow that, it's good to know.
> Also, does it make any sense ? I do not think so, and I would really
> consider the fact that we allow that as a bug. We should not allow
> that otherwise it unnecessarily extending the test matrix.
>
> What people think about restricting bigalloc _only_ for 4k block
> size file systems ?
I agree with you that we should forbid user to use bigalloc feature with
block size = 1k or 2k because I guess no one really use it, at least in
Taobao we always use bigalloc feature with block size = 4k.
FWIW, recently I am considering whether we could remove 'data=journal'
and 'data=writeback' mode. 'data=journal' mode hurts performance
dramatically. Further, 'data=writeback' seems also useless, especially
after we have 'no journal' feature. TBH, these modes are lack of tests.
Maybe this is a crazy idea in my mind.
Regards,
- Zheng
--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] ext4: fix overhead calculation in bigalloc filesystem (Re: ... )
2013-02-22 3:03 ` Zheng Liu
@ 2013-02-22 4:05 ` Theodore Ts'o
2013-02-22 8:04 ` Lukáš Czerner
2013-02-22 13:18 ` Zheng Liu
0 siblings, 2 replies; 19+ messages in thread
From: Theodore Ts'o @ 2013-02-22 4:05 UTC (permalink / raw)
To: Lukáš Czerner, linux-ext4
On Fri, Feb 22, 2013 at 11:03:27AM +0800, Zheng Liu wrote:
>
> I agree with you that we should forbid user to use bigalloc feature with
> block size = 1k or 2k because I guess no one really use it, at least in
> Taobao we always use bigalloc feature with block size = 4k.
The main reason why file systems with 1k or 2k (with or without
bigalloc) is that it's useful is that it's a good way of testing what
happens on an architecture with a 16k page size and a 4k blocksize. I
am regularly testing with a 1k blocksize because it catches problems
that would otherwise only show up on PowerPC or Intanium platforms.
I'm not testing with bigalloc plus 1k block size, though, I admit.
> FWIW, recently I am considering whether we could remove 'data=journal'
> and 'data=writeback' mode. 'data=journal' mode hurts performance
> dramatically. Further, 'data=writeback' seems also useless, especially
> after we have 'no journal' feature. TBH, these modes are lack of tests.
> Maybe this is a crazy idea in my mind.
As far as data=writeback and data=ordered are concerned, the only
difference is a single call to ext4_jbd2_file_end() in
ext4_ordered_write_end(). In fact, it looks like we could do
something like the following attached patch to simplify the code and
improve code coverage from a testing perspective. (Note: patch not
yet tested!)
As far as "data=journalled", it's a bit more complicated but I do have
a sentimental attachment to it, since it's something which no other
file system has. I have been regularly testing it, and it's something
which has been pretty stable for quite a while now.
If there was a mode that I'd be tempted to get rid of, it would be the
combined data=ordered/data=writeback modes. The main reason why we
keep it is because of a concern of buggy applications that depend on
the implied fsync() of data=ordered mode at each commit. However,
ext4 has been around for long enough that I think most of the buggy
applications have been fixed by now. And of course, those buggy
applications will lose in the same way when they are using btrfs and
xfs. Something to consider....
- Ted
commit d075b5c3031752a4c41642ff505c3302e5321940
Author: Theodore Ts'o <tytso@mit.edu>
Date: Thu Feb 21 23:04:59 2013 -0500
ext4: collapse handling of data=ordered and data=writeback codepaths
The only difference between how we handle data=ordered and
data=writeback is a single call to ext4_jbd2_file_inode(). Eliminate
code duplication by factoring out redundant the code paths.
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 6e16c18..85dfd49 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -1373,6 +1373,7 @@ enum {
EXT4_STATE_DIOREAD_LOCK, /* Disable support for dio read
nolocking */
EXT4_STATE_MAY_INLINE_DATA, /* may have in-inode data */
+ EXT4_STATE_ORDERED_MODE, /* data=ordered mode */
};
#define EXT4_INODE_BIT_FNS(name, field, offset) \
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 95a0c62..2e338a6 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -1055,77 +1055,36 @@ static int ext4_generic_write_end(struct file *file,
* ext4 never places buffers on inode->i_mapping->private_list. metadata
* buffers are managed internally.
*/
-static int ext4_ordered_write_end(struct file *file,
- struct address_space *mapping,
- loff_t pos, unsigned len, unsigned copied,
- struct page *page, void *fsdata)
+static int ext4_write_end(struct file *file,
+ struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct page *page, void *fsdata)
{
handle_t *handle = ext4_journal_current_handle();
struct inode *inode = mapping->host;
int ret = 0, ret2;
trace_ext4_ordered_write_end(inode, pos, len, copied);
- ret = ext4_jbd2_file_inode(handle, inode);
-
- if (ret == 0) {
- ret2 = ext4_generic_write_end(file, mapping, pos, len, copied,
- page, fsdata);
- copied = ret2;
- if (pos + len > inode->i_size && ext4_can_truncate(inode))
- /* if we have allocated more blocks and copied
- * less. We will have blocks allocated outside
- * inode->i_size. So truncate them
- */
- ext4_orphan_add(handle, inode);
- if (ret2 < 0)
- ret = ret2;
- } else {
- unlock_page(page);
- page_cache_release(page);
- }
-
- ret2 = ext4_journal_stop(handle);
- if (!ret)
- ret = ret2;
-
- if (pos + len > inode->i_size) {
- ext4_truncate_failed_write(inode);
- /*
- * If truncate failed early the inode might still be
- * on the orphan list; we need to make sure the inode
- * is removed from the orphan list in that case.
- */
- if (inode->i_nlink)
- ext4_orphan_del(NULL, inode);
+ if (ext4_test_inode_state(inode, EXT4_STATE_ORDERED_MODE)) {
+ ret = ext4_jbd2_file_inode(handle, inode);
+ if (ret) {
+ unlock_page(page);
+ page_cache_release(page);
+ goto errout;
+ }
}
-
- return ret ? ret : copied;
-}
-
-static int ext4_writeback_write_end(struct file *file,
- struct address_space *mapping,
- loff_t pos, unsigned len, unsigned copied,
- struct page *page, void *fsdata)
-{
- handle_t *handle = ext4_journal_current_handle();
- struct inode *inode = mapping->host;
- int ret = 0, ret2;
-
- trace_ext4_writeback_write_end(inode, pos, len, copied);
- ret2 = ext4_generic_write_end(file, mapping, pos, len, copied,
- page, fsdata);
- copied = ret2;
+ copied = ext4_generic_write_end(file, mapping, pos, len, copied,
+ page, fsdata);
+ if (copied < 0)
+ ret = copied;
if (pos + len > inode->i_size && ext4_can_truncate(inode))
/* if we have allocated more blocks and copied
* less. We will have blocks allocated outside
* inode->i_size. So truncate them
*/
ext4_orphan_add(handle, inode);
-
- if (ret2 < 0)
- ret = ret2;
-
+errout:
ret2 = ext4_journal_stop(handle);
if (!ret)
ret = ret2;
@@ -2656,18 +2615,9 @@ static int ext4_da_write_end(struct file *file,
unsigned long start, end;
int write_mode = (int)(unsigned long)fsdata;
- if (write_mode == FALL_BACK_TO_NONDELALLOC) {
- switch (ext4_inode_journal_mode(inode)) {
- case EXT4_INODE_ORDERED_DATA_MODE:
- return ext4_ordered_write_end(file, mapping, pos,
- len, copied, page, fsdata);
- case EXT4_INODE_WRITEBACK_DATA_MODE:
- return ext4_writeback_write_end(file, mapping, pos,
- len, copied, page, fsdata);
- default:
- BUG();
- }
- }
+ if (write_mode == FALL_BACK_TO_NONDELALLOC)
+ return ext4_write_end(file, mapping, pos,
+ len, copied, page, fsdata);
trace_ext4_da_write_end(inode, pos, len, copied);
start = pos & (PAGE_CACHE_SIZE - 1);
@@ -3172,27 +3122,12 @@ static int ext4_journalled_set_page_dirty(struct page *page)
return __set_page_dirty_nobuffers(page);
}
-static const struct address_space_operations ext4_ordered_aops = {
+static const struct address_space_operations ext4_aops = {
.readpage = ext4_readpage,
.readpages = ext4_readpages,
.writepage = ext4_writepage,
.write_begin = ext4_write_begin,
- .write_end = ext4_ordered_write_end,
- .bmap = ext4_bmap,
- .invalidatepage = ext4_invalidatepage,
- .releasepage = ext4_releasepage,
- .direct_IO = ext4_direct_IO,
- .migratepage = buffer_migrate_page,
- .is_partially_uptodate = block_is_partially_uptodate,
- .error_remove_page = generic_error_remove_page,
-};
-
-static const struct address_space_operations ext4_writeback_aops = {
- .readpage = ext4_readpage,
- .readpages = ext4_readpages,
- .writepage = ext4_writepage,
- .write_begin = ext4_write_begin,
- .write_end = ext4_writeback_write_end,
+ .write_end = ext4_write_end,
.bmap = ext4_bmap,
.invalidatepage = ext4_invalidatepage,
.releasepage = ext4_releasepage,
@@ -3237,23 +3172,21 @@ void ext4_set_aops(struct inode *inode)
{
switch (ext4_inode_journal_mode(inode)) {
case EXT4_INODE_ORDERED_DATA_MODE:
- if (test_opt(inode->i_sb, DELALLOC))
- inode->i_mapping->a_ops = &ext4_da_aops;
- else
- inode->i_mapping->a_ops = &ext4_ordered_aops;
+ ext4_set_inode_state(inode, EXT4_STATE_ORDERED_MODE);
break;
case EXT4_INODE_WRITEBACK_DATA_MODE:
- if (test_opt(inode->i_sb, DELALLOC))
- inode->i_mapping->a_ops = &ext4_da_aops;
- else
- inode->i_mapping->a_ops = &ext4_writeback_aops;
+ ext4_clear_inode_state(inode, EXT4_STATE_ORDERED_MODE);
break;
case EXT4_INODE_JOURNAL_DATA_MODE:
inode->i_mapping->a_ops = &ext4_journalled_aops;
- break;
+ return;
default:
BUG();
}
+ if (test_opt(inode->i_sb, DELALLOC))
+ inode->i_mapping->a_ops = &ext4_da_aops;
+ else
+ inode->i_mapping->a_ops = &ext4_aops;
}
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH] ext4: fix free clusters calculation in bigalloc filesystem
2013-02-21 8:01 [PATCH] ext4: fix free clusters calculation in bigalloc filesystem Lukas Czerner
2013-02-21 12:15 ` [PATCH] ext4: fix overhead calculation in bigalloc filesystem (Re: ... ) Zheng Liu
@ 2013-02-22 5:10 ` Theodore Ts'o
2013-02-22 7:57 ` Lukáš Czerner
2013-02-22 8:39 ` [PATCH v2] " Lukas Czerner
2 siblings, 1 reply; 19+ messages in thread
From: Theodore Ts'o @ 2013-02-22 5:10 UTC (permalink / raw)
To: Lukas Czerner; +Cc: linux-ext4
On Thu, Feb 21, 2013 at 09:01:05AM +0100, Lukas Czerner wrote:
>
> Moreover when calculating number of root clusters we should be using
> macro EXT4_NUM_B2C() instead of EXT4_C2B() otherwise the result will
> usually be off by one.
That should be "instead of EXT4_B2C()", and I don't think this is
true, since the number of blocks should always be a multiple of the
cluster ratio. So the use of EXT4_B2C() is a bit of an optimization
(it avoids an add and mask operation), but it's probably not a
measurable optimizatoin in practice.
- Ted
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] ext4: fix free clusters calculation in bigalloc filesystem
2013-02-22 5:10 ` [PATCH] ext4: fix free clusters calculation in bigalloc filesystem Theodore Ts'o
@ 2013-02-22 7:57 ` Lukáš Czerner
0 siblings, 0 replies; 19+ messages in thread
From: Lukáš Czerner @ 2013-02-22 7:57 UTC (permalink / raw)
To: Theodore Ts'o; +Cc: Lukas Czerner, linux-ext4
On Fri, 22 Feb 2013, Theodore Ts'o wrote:
> Date: Fri, 22 Feb 2013 00:10:48 -0500
> From: Theodore Ts'o <tytso@mit.edu>
> To: Lukas Czerner <lczerner@redhat.com>
> Cc: linux-ext4@vger.kernel.org
> Subject: Re: [PATCH] ext4: fix free clusters calculation in bigalloc
> filesystem
>
> On Thu, Feb 21, 2013 at 09:01:05AM +0100, Lukas Czerner wrote:
> >
> > Moreover when calculating number of root clusters we should be using
> > macro EXT4_NUM_B2C() instead of EXT4_C2B() otherwise the result will
> > usually be off by one.
>
> That should be "instead of EXT4_B2C()", and I don't think this is
> true, since the number of blocks should always be a multiple of the
> cluster ratio. So the use of EXT4_B2C() is a bit of an optimization
> (it avoids an add and mask operation), but it's probably not a
> measurable optimizatoin in practice.
>
> - Ted
Oh right it was EXT4_B2C(), I'll update the description. Even though
it should always be a multiple of cluster ratio it's really bad
precedence for the use of EXT4_B2C() since it is confusing enough
as it is with blocks/clusters.
I'll resend.
-Lukas
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] ext4: fix overhead calculation in bigalloc filesystem (Re: ... )
2013-02-22 4:05 ` Theodore Ts'o
@ 2013-02-22 8:04 ` Lukáš Czerner
2013-02-22 13:18 ` Zheng Liu
1 sibling, 0 replies; 19+ messages in thread
From: Lukáš Czerner @ 2013-02-22 8:04 UTC (permalink / raw)
To: Theodore Ts'o; +Cc: Lukáš Czerner, linux-ext4
[-- Attachment #1: Type: TEXT/PLAIN, Size: 9600 bytes --]
On Thu, 21 Feb 2013, Theodore Ts'o wrote:
> Date: Thu, 21 Feb 2013 23:05:44 -0500
> From: Theodore Ts'o <tytso@mit.edu>
> To: Lukáš Czerner <lczerner@redhat.com>, linux-ext4@vger.kernel.org
> Subject: Re: [PATCH] ext4: fix overhead calculation in bigalloc filesystem
> (Re: ... )
>
> On Fri, Feb 22, 2013 at 11:03:27AM +0800, Zheng Liu wrote:
> >
> > I agree with you that we should forbid user to use bigalloc feature with
> > block size = 1k or 2k because I guess no one really use it, at least in
> > Taobao we always use bigalloc feature with block size = 4k.
>
> The main reason why file systems with 1k or 2k (with or without
> bigalloc) is that it's useful is that it's a good way of testing what
> happens on an architecture with a 16k page size and a 4k blocksize. I
> am regularly testing with a 1k blocksize because it catches problems
> that would otherwise only show up on PowerPC or Intanium platforms.
> I'm not testing with bigalloc plus 1k block size, though, I admit.
I agree having block size smaller than 4k is useful not only for
testing purposes. However in my opinion with bigalloc it is entirely
unnecessary to allow those sizes.
-Lukas
>
> > FWIW, recently I am considering whether we could remove 'data=journal'
> > and 'data=writeback' mode. 'data=journal' mode hurts performance
> > dramatically. Further, 'data=writeback' seems also useless, especially
> > after we have 'no journal' feature. TBH, these modes are lack of tests.
> > Maybe this is a crazy idea in my mind.
>
> As far as data=writeback and data=ordered are concerned, the only
> difference is a single call to ext4_jbd2_file_end() in
> ext4_ordered_write_end(). In fact, it looks like we could do
> something like the following attached patch to simplify the code and
> improve code coverage from a testing perspective. (Note: patch not
> yet tested!)
>
> As far as "data=journalled", it's a bit more complicated but I do have
> a sentimental attachment to it, since it's something which no other
> file system has. I have been regularly testing it, and it's something
> which has been pretty stable for quite a while now.
>
> If there was a mode that I'd be tempted to get rid of, it would be the
> combined data=ordered/data=writeback modes. The main reason why we
> keep it is because of a concern of buggy applications that depend on
> the implied fsync() of data=ordered mode at each commit. However,
> ext4 has been around for long enough that I think most of the buggy
> applications have been fixed by now. And of course, those buggy
> applications will lose in the same way when they are using btrfs and
> xfs. Something to consider....
>
> - Ted
>
> commit d075b5c3031752a4c41642ff505c3302e5321940
> Author: Theodore Ts'o <tytso@mit.edu>
> Date: Thu Feb 21 23:04:59 2013 -0500
>
> ext4: collapse handling of data=ordered and data=writeback codepaths
>
> The only difference between how we handle data=ordered and
> data=writeback is a single call to ext4_jbd2_file_inode(). Eliminate
> code duplication by factoring out redundant the code paths.
>
> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
>
> diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
> index 6e16c18..85dfd49 100644
> --- a/fs/ext4/ext4.h
> +++ b/fs/ext4/ext4.h
> @@ -1373,6 +1373,7 @@ enum {
> EXT4_STATE_DIOREAD_LOCK, /* Disable support for dio read
> nolocking */
> EXT4_STATE_MAY_INLINE_DATA, /* may have in-inode data */
> + EXT4_STATE_ORDERED_MODE, /* data=ordered mode */
> };
>
> #define EXT4_INODE_BIT_FNS(name, field, offset) \
> diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
> index 95a0c62..2e338a6 100644
> --- a/fs/ext4/inode.c
> +++ b/fs/ext4/inode.c
> @@ -1055,77 +1055,36 @@ static int ext4_generic_write_end(struct file *file,
> * ext4 never places buffers on inode->i_mapping->private_list. metadata
> * buffers are managed internally.
> */
> -static int ext4_ordered_write_end(struct file *file,
> - struct address_space *mapping,
> - loff_t pos, unsigned len, unsigned copied,
> - struct page *page, void *fsdata)
> +static int ext4_write_end(struct file *file,
> + struct address_space *mapping,
> + loff_t pos, unsigned len, unsigned copied,
> + struct page *page, void *fsdata)
> {
> handle_t *handle = ext4_journal_current_handle();
> struct inode *inode = mapping->host;
> int ret = 0, ret2;
>
> trace_ext4_ordered_write_end(inode, pos, len, copied);
> - ret = ext4_jbd2_file_inode(handle, inode);
> -
> - if (ret == 0) {
> - ret2 = ext4_generic_write_end(file, mapping, pos, len, copied,
> - page, fsdata);
> - copied = ret2;
> - if (pos + len > inode->i_size && ext4_can_truncate(inode))
> - /* if we have allocated more blocks and copied
> - * less. We will have blocks allocated outside
> - * inode->i_size. So truncate them
> - */
> - ext4_orphan_add(handle, inode);
> - if (ret2 < 0)
> - ret = ret2;
> - } else {
> - unlock_page(page);
> - page_cache_release(page);
> - }
> -
> - ret2 = ext4_journal_stop(handle);
> - if (!ret)
> - ret = ret2;
> -
> - if (pos + len > inode->i_size) {
> - ext4_truncate_failed_write(inode);
> - /*
> - * If truncate failed early the inode might still be
> - * on the orphan list; we need to make sure the inode
> - * is removed from the orphan list in that case.
> - */
> - if (inode->i_nlink)
> - ext4_orphan_del(NULL, inode);
> + if (ext4_test_inode_state(inode, EXT4_STATE_ORDERED_MODE)) {
> + ret = ext4_jbd2_file_inode(handle, inode);
> + if (ret) {
> + unlock_page(page);
> + page_cache_release(page);
> + goto errout;
> + }
> }
>
> -
> - return ret ? ret : copied;
> -}
> -
> -static int ext4_writeback_write_end(struct file *file,
> - struct address_space *mapping,
> - loff_t pos, unsigned len, unsigned copied,
> - struct page *page, void *fsdata)
> -{
> - handle_t *handle = ext4_journal_current_handle();
> - struct inode *inode = mapping->host;
> - int ret = 0, ret2;
> -
> - trace_ext4_writeback_write_end(inode, pos, len, copied);
> - ret2 = ext4_generic_write_end(file, mapping, pos, len, copied,
> - page, fsdata);
> - copied = ret2;
> + copied = ext4_generic_write_end(file, mapping, pos, len, copied,
> + page, fsdata);
> + if (copied < 0)
> + ret = copied;
> if (pos + len > inode->i_size && ext4_can_truncate(inode))
> /* if we have allocated more blocks and copied
> * less. We will have blocks allocated outside
> * inode->i_size. So truncate them
> */
> ext4_orphan_add(handle, inode);
> -
> - if (ret2 < 0)
> - ret = ret2;
> -
> +errout:
> ret2 = ext4_journal_stop(handle);
> if (!ret)
> ret = ret2;
> @@ -2656,18 +2615,9 @@ static int ext4_da_write_end(struct file *file,
> unsigned long start, end;
> int write_mode = (int)(unsigned long)fsdata;
>
> - if (write_mode == FALL_BACK_TO_NONDELALLOC) {
> - switch (ext4_inode_journal_mode(inode)) {
> - case EXT4_INODE_ORDERED_DATA_MODE:
> - return ext4_ordered_write_end(file, mapping, pos,
> - len, copied, page, fsdata);
> - case EXT4_INODE_WRITEBACK_DATA_MODE:
> - return ext4_writeback_write_end(file, mapping, pos,
> - len, copied, page, fsdata);
> - default:
> - BUG();
> - }
> - }
> + if (write_mode == FALL_BACK_TO_NONDELALLOC)
> + return ext4_write_end(file, mapping, pos,
> + len, copied, page, fsdata);
>
> trace_ext4_da_write_end(inode, pos, len, copied);
> start = pos & (PAGE_CACHE_SIZE - 1);
> @@ -3172,27 +3122,12 @@ static int ext4_journalled_set_page_dirty(struct page *page)
> return __set_page_dirty_nobuffers(page);
> }
>
> -static const struct address_space_operations ext4_ordered_aops = {
> +static const struct address_space_operations ext4_aops = {
> .readpage = ext4_readpage,
> .readpages = ext4_readpages,
> .writepage = ext4_writepage,
> .write_begin = ext4_write_begin,
> - .write_end = ext4_ordered_write_end,
> - .bmap = ext4_bmap,
> - .invalidatepage = ext4_invalidatepage,
> - .releasepage = ext4_releasepage,
> - .direct_IO = ext4_direct_IO,
> - .migratepage = buffer_migrate_page,
> - .is_partially_uptodate = block_is_partially_uptodate,
> - .error_remove_page = generic_error_remove_page,
> -};
> -
> -static const struct address_space_operations ext4_writeback_aops = {
> - .readpage = ext4_readpage,
> - .readpages = ext4_readpages,
> - .writepage = ext4_writepage,
> - .write_begin = ext4_write_begin,
> - .write_end = ext4_writeback_write_end,
> + .write_end = ext4_write_end,
> .bmap = ext4_bmap,
> .invalidatepage = ext4_invalidatepage,
> .releasepage = ext4_releasepage,
> @@ -3237,23 +3172,21 @@ void ext4_set_aops(struct inode *inode)
> {
> switch (ext4_inode_journal_mode(inode)) {
> case EXT4_INODE_ORDERED_DATA_MODE:
> - if (test_opt(inode->i_sb, DELALLOC))
> - inode->i_mapping->a_ops = &ext4_da_aops;
> - else
> - inode->i_mapping->a_ops = &ext4_ordered_aops;
> + ext4_set_inode_state(inode, EXT4_STATE_ORDERED_MODE);
> break;
> case EXT4_INODE_WRITEBACK_DATA_MODE:
> - if (test_opt(inode->i_sb, DELALLOC))
> - inode->i_mapping->a_ops = &ext4_da_aops;
> - else
> - inode->i_mapping->a_ops = &ext4_writeback_aops;
> + ext4_clear_inode_state(inode, EXT4_STATE_ORDERED_MODE);
> break;
> case EXT4_INODE_JOURNAL_DATA_MODE:
> inode->i_mapping->a_ops = &ext4_journalled_aops;
> - break;
> + return;
> default:
> BUG();
> }
> + if (test_opt(inode->i_sb, DELALLOC))
> + inode->i_mapping->a_ops = &ext4_da_aops;
> + else
> + inode->i_mapping->a_ops = &ext4_aops;
> }
>
>
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v2] ext4: fix free clusters calculation in bigalloc filesystem
2013-02-21 8:01 [PATCH] ext4: fix free clusters calculation in bigalloc filesystem Lukas Czerner
2013-02-21 12:15 ` [PATCH] ext4: fix overhead calculation in bigalloc filesystem (Re: ... ) Zheng Liu
2013-02-22 5:10 ` [PATCH] ext4: fix free clusters calculation in bigalloc filesystem Theodore Ts'o
@ 2013-02-22 8:39 ` Lukas Czerner
2 siblings, 0 replies; 19+ messages in thread
From: Lukas Czerner @ 2013-02-22 8:39 UTC (permalink / raw)
To: linux-ext4; +Cc: Lukas Czerner
ext4_has_free_clusters() should tell us whether there is enough free
clusters to allocate, however number of free clusters in the file system
is converted to blocks using EXT4_C2B() which is not only wrong use of
the macro (we should have used EXT4_NUM_B2C) but it's also completely
wrong concept since everything else is in cluster units.
Moreover when calculating number of root clusters we should be using
macro EXT4_NUM_B2C() instead of EXT4_B2C() otherwise the result might be
off by one. However r_blocks_count should always be a multiple of the
cluster ratio so doing a plain bit shift should be enough here. We
avoid using EXT4_B2C() because it's confusing.
As a result of the first problem number of free clusters is much bigger
than it should have been and ext4_has_free_clusters() would return 1 even
if there is really not enough free clusters available.
Fix this by removing the EXT4_C2B() conversion of free clusters and
using bit shift when calculating number of root clusters. This bug
affects number of xfstests tests covering file system ENOSPC situation
handling. With this patch most of the ENOSPC problems with bigalloc file
system disappear, especially the errors caused by delayed allocation not
having enough space when the actual allocation is finally requested.
Signed-off-by: Lukas Czerner <lczerner@redhat.com>
---
v2: update description, use just bit shift to calculate root_clusters
fs/ext4/balloc.c | 9 +++++++--
1 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
index cf18217..30444b0 100644
--- a/fs/ext4/balloc.c
+++ b/fs/ext4/balloc.c
@@ -482,11 +482,16 @@ static int ext4_has_free_clusters(struct ext4_sb_info *sbi,
free_clusters = percpu_counter_read_positive(fcc);
dirty_clusters = percpu_counter_read_positive(dcc);
- root_clusters = EXT4_B2C(sbi, ext4_r_blocks_count(sbi->s_es));
+
+ /*
+ * r_blocks_count should always be multiple of the cluster ratio so
+ * we are safe to do a plane bit shift only.
+ */
+ root_clusters = ext4_r_blocks_count(sbi->s_es) >> sbi->s_cluster_bits;
if (free_clusters - (nclusters + root_clusters + dirty_clusters) <
EXT4_FREECLUSTERS_WATERMARK) {
- free_clusters = EXT4_C2B(sbi, percpu_counter_sum_positive(fcc));
+ free_clusters = percpu_counter_sum_positive(fcc);
dirty_clusters = percpu_counter_sum_positive(dcc);
}
/* Check whether we have space after accounting for current
--
1.7.7.6
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH] ext4: fix overhead calculation in bigalloc filesystem (Re: ... )
2013-02-22 4:05 ` Theodore Ts'o
2013-02-22 8:04 ` Lukáš Czerner
@ 2013-02-22 13:18 ` Zheng Liu
2013-02-22 15:20 ` Theodore Ts'o
1 sibling, 1 reply; 19+ messages in thread
From: Zheng Liu @ 2013-02-22 13:18 UTC (permalink / raw)
To: Theodore Ts'o; +Cc: Lukáš Czerner, linux-ext4
On Thu, Feb 21, 2013 at 11:05:44PM -0500, Theodore Ts'o wrote:
> On Fri, Feb 22, 2013 at 11:03:27AM +0800, Zheng Liu wrote:
> >
> > I agree with you that we should forbid user to use bigalloc feature with
> > block size = 1k or 2k because I guess no one really use it, at least in
> > Taobao we always use bigalloc feature with block size = 4k.
>
> The main reason why file systems with 1k or 2k (with or without
> bigalloc) is that it's useful is that it's a good way of testing what
> happens on an architecture with a 16k page size and a 4k blocksize. I
> am regularly testing with a 1k blocksize because it catches problems
> that would otherwise only show up on PowerPC or Intanium platforms.
> I'm not testing with bigalloc plus 1k block size, though, I admit.
>
> > FWIW, recently I am considering whether we could remove 'data=journal'
> > and 'data=writeback' mode. 'data=journal' mode hurts performance
> > dramatically. Further, 'data=writeback' seems also useless, especially
> > after we have 'no journal' feature. TBH, these modes are lack of tests.
> > Maybe this is a crazy idea in my mind.
>
> As far as data=writeback and data=ordered are concerned, the only
> difference is a single call to ext4_jbd2_file_end() in
> ext4_ordered_write_end(). In fact, it looks like we could do
> something like the following attached patch to simplify the code and
> improve code coverage from a testing perspective. (Note: patch not
> yet tested!)
>
> As far as "data=journalled", it's a bit more complicated but I do have
> a sentimental attachment to it, since it's something which no other
> file system has. I have been regularly testing it, and it's something
> which has been pretty stable for quite a while now.
Indeed, it seems that other file systems don't have this feature AFAIK.
>
> If there was a mode that I'd be tempted to get rid of, it would be the
> combined data=ordered/data=writeback modes. The main reason why we
> keep it is because of a concern of buggy applications that depend on
> the implied fsync() of data=ordered mode at each commit. However,
> ext4 has been around for long enough that I think most of the buggy
> applications have been fixed by now. And of course, those buggy
> applications will lose in the same way when they are using btrfs and
> xfs. Something to consider....
IMHO, the application shouldn't depend on a kernel feature. So maybe it
is time to highlight this buggy usage.
>
> - Ted
>
> commit d075b5c3031752a4c41642ff505c3302e5321940
> Author: Theodore Ts'o <tytso@mit.edu>
> Date: Thu Feb 21 23:04:59 2013 -0500
>
> ext4: collapse handling of data=ordered and data=writeback codepaths
>
> The only difference between how we handle data=ordered and
> data=writeback is a single call to ext4_jbd2_file_inode(). Eliminate
> code duplication by factoring out redundant the code paths.
>
> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Just one minor comment below. Otherwise the patch looks good to me, and
it can pass in xfstests with 'data=ordered' and 'data=writeback'.
Reviewed-by: Zheng Liu <wenqing.lz@taobao.com>
>
> diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
> index 6e16c18..85dfd49 100644
> --- a/fs/ext4/ext4.h
> +++ b/fs/ext4/ext4.h
> @@ -1373,6 +1373,7 @@ enum {
> EXT4_STATE_DIOREAD_LOCK, /* Disable support for dio read
> nolocking */
> EXT4_STATE_MAY_INLINE_DATA, /* may have in-inode data */
> + EXT4_STATE_ORDERED_MODE, /* data=ordered mode */
> };
>
> #define EXT4_INODE_BIT_FNS(name, field, offset) \
> diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
> index 95a0c62..2e338a6 100644
> --- a/fs/ext4/inode.c
> +++ b/fs/ext4/inode.c
> @@ -1055,77 +1055,36 @@ static int ext4_generic_write_end(struct file *file,
> * ext4 never places buffers on inode->i_mapping->private_list. metadata
> * buffers are managed internally.
> */
> -static int ext4_ordered_write_end(struct file *file,
> - struct address_space *mapping,
> - loff_t pos, unsigned len, unsigned copied,
> - struct page *page, void *fsdata)
> +static int ext4_write_end(struct file *file,
> + struct address_space *mapping,
> + loff_t pos, unsigned len, unsigned copied,
> + struct page *page, void *fsdata)
> {
> handle_t *handle = ext4_journal_current_handle();
> struct inode *inode = mapping->host;
> int ret = 0, ret2;
>
> trace_ext4_ordered_write_end(inode, pos, len, copied);
Here this function needs to be renamed with trace_ext4_write_end().
Regards,
- Zheng
> - ret = ext4_jbd2_file_inode(handle, inode);
> -
> - if (ret == 0) {
> - ret2 = ext4_generic_write_end(file, mapping, pos, len, copied,
> - page, fsdata);
> - copied = ret2;
> - if (pos + len > inode->i_size && ext4_can_truncate(inode))
> - /* if we have allocated more blocks and copied
> - * less. We will have blocks allocated outside
> - * inode->i_size. So truncate them
> - */
> - ext4_orphan_add(handle, inode);
> - if (ret2 < 0)
> - ret = ret2;
> - } else {
> - unlock_page(page);
> - page_cache_release(page);
> - }
> -
> - ret2 = ext4_journal_stop(handle);
> - if (!ret)
> - ret = ret2;
> -
> - if (pos + len > inode->i_size) {
> - ext4_truncate_failed_write(inode);
> - /*
> - * If truncate failed early the inode might still be
> - * on the orphan list; we need to make sure the inode
> - * is removed from the orphan list in that case.
> - */
> - if (inode->i_nlink)
> - ext4_orphan_del(NULL, inode);
> + if (ext4_test_inode_state(inode, EXT4_STATE_ORDERED_MODE)) {
> + ret = ext4_jbd2_file_inode(handle, inode);
> + if (ret) {
> + unlock_page(page);
> + page_cache_release(page);
> + goto errout;
> + }
> }
>
> -
> - return ret ? ret : copied;
> -}
> -
> -static int ext4_writeback_write_end(struct file *file,
> - struct address_space *mapping,
> - loff_t pos, unsigned len, unsigned copied,
> - struct page *page, void *fsdata)
> -{
> - handle_t *handle = ext4_journal_current_handle();
> - struct inode *inode = mapping->host;
> - int ret = 0, ret2;
> -
> - trace_ext4_writeback_write_end(inode, pos, len, copied);
> - ret2 = ext4_generic_write_end(file, mapping, pos, len, copied,
> - page, fsdata);
> - copied = ret2;
> + copied = ext4_generic_write_end(file, mapping, pos, len, copied,
> + page, fsdata);
> + if (copied < 0)
> + ret = copied;
> if (pos + len > inode->i_size && ext4_can_truncate(inode))
> /* if we have allocated more blocks and copied
> * less. We will have blocks allocated outside
> * inode->i_size. So truncate them
> */
> ext4_orphan_add(handle, inode);
> -
> - if (ret2 < 0)
> - ret = ret2;
> -
> +errout:
> ret2 = ext4_journal_stop(handle);
> if (!ret)
> ret = ret2;
> @@ -2656,18 +2615,9 @@ static int ext4_da_write_end(struct file *file,
> unsigned long start, end;
> int write_mode = (int)(unsigned long)fsdata;
>
> - if (write_mode == FALL_BACK_TO_NONDELALLOC) {
> - switch (ext4_inode_journal_mode(inode)) {
> - case EXT4_INODE_ORDERED_DATA_MODE:
> - return ext4_ordered_write_end(file, mapping, pos,
> - len, copied, page, fsdata);
> - case EXT4_INODE_WRITEBACK_DATA_MODE:
> - return ext4_writeback_write_end(file, mapping, pos,
> - len, copied, page, fsdata);
> - default:
> - BUG();
> - }
> - }
> + if (write_mode == FALL_BACK_TO_NONDELALLOC)
> + return ext4_write_end(file, mapping, pos,
> + len, copied, page, fsdata);
>
> trace_ext4_da_write_end(inode, pos, len, copied);
> start = pos & (PAGE_CACHE_SIZE - 1);
> @@ -3172,27 +3122,12 @@ static int ext4_journalled_set_page_dirty(struct page *page)
> return __set_page_dirty_nobuffers(page);
> }
>
> -static const struct address_space_operations ext4_ordered_aops = {
> +static const struct address_space_operations ext4_aops = {
> .readpage = ext4_readpage,
> .readpages = ext4_readpages,
> .writepage = ext4_writepage,
> .write_begin = ext4_write_begin,
> - .write_end = ext4_ordered_write_end,
> - .bmap = ext4_bmap,
> - .invalidatepage = ext4_invalidatepage,
> - .releasepage = ext4_releasepage,
> - .direct_IO = ext4_direct_IO,
> - .migratepage = buffer_migrate_page,
> - .is_partially_uptodate = block_is_partially_uptodate,
> - .error_remove_page = generic_error_remove_page,
> -};
> -
> -static const struct address_space_operations ext4_writeback_aops = {
> - .readpage = ext4_readpage,
> - .readpages = ext4_readpages,
> - .writepage = ext4_writepage,
> - .write_begin = ext4_write_begin,
> - .write_end = ext4_writeback_write_end,
> + .write_end = ext4_write_end,
> .bmap = ext4_bmap,
> .invalidatepage = ext4_invalidatepage,
> .releasepage = ext4_releasepage,
> @@ -3237,23 +3172,21 @@ void ext4_set_aops(struct inode *inode)
> {
> switch (ext4_inode_journal_mode(inode)) {
> case EXT4_INODE_ORDERED_DATA_MODE:
> - if (test_opt(inode->i_sb, DELALLOC))
> - inode->i_mapping->a_ops = &ext4_da_aops;
> - else
> - inode->i_mapping->a_ops = &ext4_ordered_aops;
> + ext4_set_inode_state(inode, EXT4_STATE_ORDERED_MODE);
> break;
> case EXT4_INODE_WRITEBACK_DATA_MODE:
> - if (test_opt(inode->i_sb, DELALLOC))
> - inode->i_mapping->a_ops = &ext4_da_aops;
> - else
> - inode->i_mapping->a_ops = &ext4_writeback_aops;
> + ext4_clear_inode_state(inode, EXT4_STATE_ORDERED_MODE);
> break;
> case EXT4_INODE_JOURNAL_DATA_MODE:
> inode->i_mapping->a_ops = &ext4_journalled_aops;
> - break;
> + return;
> default:
> BUG();
> }
> + if (test_opt(inode->i_sb, DELALLOC))
> + inode->i_mapping->a_ops = &ext4_da_aops;
> + else
> + inode->i_mapping->a_ops = &ext4_aops;
> }
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] ext4: fix overhead calculation in bigalloc filesystem (Re: ... )
2013-02-22 13:18 ` Zheng Liu
@ 2013-02-22 15:20 ` Theodore Ts'o
2013-02-22 16:26 ` Zheng Liu
2013-03-24 12:29 ` [PATCH] ext4: fold ext4_generic_write_end into ext4_write_end Zheng Liu
0 siblings, 2 replies; 19+ messages in thread
From: Theodore Ts'o @ 2013-02-22 15:20 UTC (permalink / raw)
To: Lukáš Czerner, linux-ext4
On Fri, Feb 22, 2013 at 09:18:12PM +0800, Zheng Liu wrote:
> > If there was a mode that I'd be tempted to get rid of, it would be the
> > combined data=ordered/data=writeback modes. The main reason why we
> > keep it is because of a concern of buggy applications that depend on
> > the implied fsync() of data=ordered mode at each commit. However,
> > ext4 has been around for long enough that I think most of the buggy
> > applications have been fixed by now. And of course, those buggy
> > applications will lose in the same way when they are using btrfs and
> > xfs. Something to consider....
>
> IMHO, the application shouldn't depend on a kernel feature. So maybe it
> is time to highlight this buggy usage.
Oh, agreed. The question is how many people want us to keep the ext3
semantics to support those buggy applications. To the extent that
distros are considering using ext4 to support ext3 file systems, there
might be a desire to maintain (as closely as possible) ext3 semantics,
even those that support buggy applications. The primary problem is
that the when comes down to application developers versus file system
developers, the application developers vastly outnumber us. :-)
> Just one minor comment below. Otherwise the patch looks good to me, and
> it can pass in xfstests with 'data=ordered' and 'data=writeback'.
I hadn't bothered testing it yet because I'm focused on testing
and cleaning up the set of patches for the merge window --- and this
change is clearly for the next merge window. Thanks for testing it!
> > trace_ext4_ordered_write_end(inode, pos, len, copied);
>
> Here this function needs to be renamed with trace_ext4_write_end().
Yes, agreed.
I also need to get rid of trace_ext4_writeback_write_end() in
include/trace/events/ext4.h.
The other thing that needs to be done --- probably in a separate
commit, just to make things easier to review for correctness, is now
that we've folded ext4_writeback_write_end() and ext4_ordered_write_end()
into a single function, we now have a single user of
ext4_generic_write_end(), so we can now fold ext4_generic_write_end()
into ext4_write_end().
- Ted
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] ext4: fix overhead calculation in bigalloc filesystem (Re: ... )
2013-02-22 15:20 ` Theodore Ts'o
@ 2013-02-22 16:26 ` Zheng Liu
2013-03-24 12:29 ` [PATCH] ext4: fold ext4_generic_write_end into ext4_write_end Zheng Liu
1 sibling, 0 replies; 19+ messages in thread
From: Zheng Liu @ 2013-02-22 16:26 UTC (permalink / raw)
To: Theodore Ts'o; +Cc: Lukáš Czerner, linux-ext4
On Fri, Feb 22, 2013 at 10:20:42AM -0500, Theodore Ts'o wrote:
> On Fri, Feb 22, 2013 at 09:18:12PM +0800, Zheng Liu wrote:
> > > If there was a mode that I'd be tempted to get rid of, it would be the
> > > combined data=ordered/data=writeback modes. The main reason why we
> > > keep it is because of a concern of buggy applications that depend on
> > > the implied fsync() of data=ordered mode at each commit. However,
> > > ext4 has been around for long enough that I think most of the buggy
> > > applications have been fixed by now. And of course, those buggy
> > > applications will lose in the same way when they are using btrfs and
> > > xfs. Something to consider....
> >
> > IMHO, the application shouldn't depend on a kernel feature. So maybe it
> > is time to highlight this buggy usage.
>
> Oh, agreed. The question is how many people want us to keep the ext3
> semantics to support those buggy applications. To the extent that
> distros are considering using ext4 to support ext3 file systems, there
> might be a desire to maintain (as closely as possible) ext3 semantics,
> even those that support buggy applications. The primary problem is
> that the when comes down to application developers versus file system
> developers, the application developers vastly outnumber us. :-)
Yes, as file system developers we always need to meet the application
developers' requirement. So it seems that we still need to keep it in
ext4. :-)
>
> > Just one minor comment below. Otherwise the patch looks good to me, and
> > it can pass in xfstests with 'data=ordered' and 'data=writeback'.
>
> I hadn't bothered testing it yet because I'm focused on testing
> and cleaning up the set of patches for the merge window --- and this
> change is clearly for the next merge window. Thanks for testing it!
I guess you are busy testing patches for the merge window. One thing I
need to let you know is this patch [1]. I really think it should be
applied for this merge window because it fixes a security hole due to my
fault. As commit log describes, a non-privilege user could cause system
crash using a truncate(1) command. So please check it.
1. http://www.spinics.net/lists/linux-ext4/msg36784.html
>
> > > trace_ext4_ordered_write_end(inode, pos, len, copied);
> >
> > Here this function needs to be renamed with trace_ext4_write_end().
>
> Yes, agreed.
>
> I also need to get rid of trace_ext4_writeback_write_end() in
> include/trace/events/ext4.h.
>
> The other thing that needs to be done --- probably in a separate
> commit, just to make things easier to review for correctness, is now
> that we've folded ext4_writeback_write_end() and ext4_ordered_write_end()
> into a single function, we now have a single user of
> ext4_generic_write_end(), so we can now fold ext4_generic_write_end()
> into ext4_write_end().
Yes, we can take a close look at in next merge window.
Thanks,
- Zheng
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH] ext4: fold ext4_generic_write_end into ext4_write_end
2013-02-22 15:20 ` Theodore Ts'o
2013-02-22 16:26 ` Zheng Liu
@ 2013-03-24 12:29 ` Zheng Liu
2013-03-25 0:07 ` Theodore Ts'o
1 sibling, 1 reply; 19+ messages in thread
From: Zheng Liu @ 2013-03-24 12:29 UTC (permalink / raw)
To: linux-ext4; +Cc: Zheng Liu, Theodore Ts'o
From: Zheng Liu <wenqing.lz@taobao.com>
After collpasing the handling of data ordered and data writeback
codepath, ext4_generic_write_end has only one caller that is
ext4_write_end. So we fold it into ext4_write_end.
Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
Cc: "Theodore Ts'o" <tytso@mit.edu>
---
This commit is against dev-test branch of ext4.
Regards,
- Zheng
fs/ext4/inode.c | 67 +++++++++++++++++++++++----------------------------------
1 file changed, 27 insertions(+), 40 deletions(-)
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 2934906..1464fcd 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -997,14 +997,32 @@ static int write_end_fn(handle_t *handle, struct buffer_head *bh)
return ext4_handle_dirty_metadata(handle, NULL, bh);
}
-static int ext4_generic_write_end(struct file *file,
- struct address_space *mapping,
- loff_t pos, unsigned len, unsigned copied,
- struct page *page, void *fsdata)
+/*
+ * We need to pick up the new inode size which generic_commit_write gave us
+ * `file' can be NULL - eg, when called from page_symlink().
+ *
+ * ext4 never places buffers on inode->i_mapping->private_list. metadata
+ * buffers are managed internally.
+ */
+static int ext4_write_end(struct file *file,
+ struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct page *page, void *fsdata)
{
- int i_size_changed = 0;
- struct inode *inode = mapping->host;
handle_t *handle = ext4_journal_current_handle();
+ struct inode *inode = mapping->host;
+ int ret = 0, ret2;
+ int i_size_changed = 0;
+
+ trace_ext4_write_end(inode, pos, len, copied);
+ if (ext4_test_inode_state(inode, EXT4_STATE_ORDERED_MODE)) {
+ ret = ext4_jbd2_file_inode(handle, inode);
+ if (ret) {
+ unlock_page(page);
+ page_cache_release(page);
+ goto errout;
+ }
+ }
if (ext4_has_inline_data(inode))
copied = ext4_write_inline_data_end(inode, pos, len,
@@ -1015,7 +1033,7 @@ static int ext4_generic_write_end(struct file *file,
/*
* No need to use i_size_read() here, the i_size
- * cannot change under us because we hold i_mutex.
+ * cannot change under us because we hole i_mutex.
*
* But it's important to update i_size while still holding page lock:
* page writeout could otherwise come in and zero beyond i_size.
@@ -1025,10 +1043,10 @@ static int ext4_generic_write_end(struct file *file,
i_size_changed = 1;
}
- if (pos + copied > EXT4_I(inode)->i_disksize) {
+ if (pos + copied > EXT4_I(inode)->i_disksize) {
/* We need to mark inode dirty even if
* new_i_size is less that inode->i_size
- * bu greater than i_disksize.(hint delalloc)
+ * but greater than i_disksize. (hint delalloc)
*/
ext4_update_i_disksize(inode, (pos + copied));
i_size_changed = 1;
@@ -1045,37 +1063,6 @@ static int ext4_generic_write_end(struct file *file,
if (i_size_changed)
ext4_mark_inode_dirty(handle, inode);
- return copied;
-}
-
-/*
- * We need to pick up the new inode size which generic_commit_write gave us
- * `file' can be NULL - eg, when called from page_symlink().
- *
- * ext4 never places buffers on inode->i_mapping->private_list. metadata
- * buffers are managed internally.
- */
-static int ext4_write_end(struct file *file,
- struct address_space *mapping,
- loff_t pos, unsigned len, unsigned copied,
- struct page *page, void *fsdata)
-{
- handle_t *handle = ext4_journal_current_handle();
- struct inode *inode = mapping->host;
- int ret = 0, ret2;
-
- trace_ext4_write_end(inode, pos, len, copied);
- if (ext4_test_inode_state(inode, EXT4_STATE_ORDERED_MODE)) {
- ret = ext4_jbd2_file_inode(handle, inode);
- if (ret) {
- unlock_page(page);
- page_cache_release(page);
- goto errout;
- }
- }
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH] ext4: fold ext4_generic_write_end into ext4_write_end
2013-03-24 12:29 ` [PATCH] ext4: fold ext4_generic_write_end into ext4_write_end Zheng Liu
@ 2013-03-25 0:07 ` Theodore Ts'o
0 siblings, 0 replies; 19+ messages in thread
From: Theodore Ts'o @ 2013-03-25 0:07 UTC (permalink / raw)
To: Zheng Liu; +Cc: linux-ext4, Zheng Liu
On Sun, Mar 24, 2013 at 08:29:16PM +0800, Zheng Liu wrote:
> From: Zheng Liu <wenqing.lz@taobao.com>
>
> After collpasing the handling of data ordered and data writeback
> codepath, ext4_generic_write_end has only one caller that is
> ext4_write_end. So we fold it into ext4_write_end.
>
> Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
> Cc: "Theodore Ts'o" <tytso@mit.edu>
Applied, thanks.
- Ted
^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2013-03-25 0:07 UTC | newest]
Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-02-21 8:01 [PATCH] ext4: fix free clusters calculation in bigalloc filesystem Lukas Czerner
2013-02-21 12:15 ` [PATCH] ext4: fix overhead calculation in bigalloc filesystem (Re: ... ) Zheng Liu
2013-02-21 12:40 ` Lukáš Czerner
2013-02-21 12:50 ` Lukáš Czerner
2013-02-21 12:52 ` Lukáš Czerner
2013-02-21 13:49 ` Zheng Liu
2013-02-21 14:56 ` Lukáš Czerner
2013-02-22 3:03 ` Zheng Liu
2013-02-22 4:05 ` Theodore Ts'o
2013-02-22 8:04 ` Lukáš Czerner
2013-02-22 13:18 ` Zheng Liu
2013-02-22 15:20 ` Theodore Ts'o
2013-02-22 16:26 ` Zheng Liu
2013-03-24 12:29 ` [PATCH] ext4: fold ext4_generic_write_end into ext4_write_end Zheng Liu
2013-03-25 0:07 ` Theodore Ts'o
2013-02-21 13:12 ` [PATCH] ext4: fix overhead calculation in bigalloc filesystem (Re: ... ) Zheng Liu
2013-02-22 5:10 ` [PATCH] ext4: fix free clusters calculation in bigalloc filesystem Theodore Ts'o
2013-02-22 7:57 ` Lukáš Czerner
2013-02-22 8:39 ` [PATCH v2] " Lukas Czerner
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).