GFS2: kernel changes to support new gfs2_grow command (Try 3)
PATCH 1/1 GFS2: kernel changes to support new gfs2_grow command (Try 3)
Hi All,
This is another revision of my gfs2 kernel patch that allows gfs2_grow to function properly.
Steve Whitehouse expressed some concerns about the previous patch and I restructured it based on his comments.
The previous patch was doing the statfs_change at file close time, under its own transaction. The current patch does the statfs_change inside the gfs2_commit_write function, which keeps it under the umbrella of the inode transaction.
I can't call ri_update to re-read the rindex file during the transaction because the transaction may have outstanding unwritten buffers attached to the rgrps that would be otherwise blown away. So instead, I created a new function, gfs2_ri_total, that will re-read the rindex file just to total the file system space for the sake of the statfs_change. The ri_update will happen later, when gfs2 realizes the version number has changed, as it happened before my patch.
Since the statfs_change is happening at write_commit time and there may be multiple writes to the rindex file for one grow operation. So one consequence of this restructuring is that instead of getting one kernel message to indicate the change, you may see several. For example, before when you did a gfs2_grow, you'd get a single message like:
GFS2: File system extended by 247876 blocks (968MB)
Now you get something like:
GFS2: File system extended by 207896 blocks (812MB)
GFS2: File system extended by 39980 blocks (156MB)
This version has also been successfully run against the hours-long "gfs2_fsck_hellfire" test that does several gfs2_grow and gfs2_fsck while interjecting file system damage. It does this repeatedly under a variety Resource Group conditions.
Regards,
Bob Peterson
Red Hat Cluster Suite
Signature · 4 lines
fs/gfs2/ops_address.c | 39 +++++++++++++++++- fs/gfs2/ops_address.h | 5 ++- fs/gfs2/rgrp.c | 106 ++++++++++++++++++++++++++++++++++++++++--------- 3 files changed, 129 insertions(+), 21 deletions(-)
fs/gfs2/ops_address.c +38 -1
@@ -1,6 +1,6 @@/* * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -* Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. +* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. * * This copyrighted material is made available to anyone wishing to use, * modify, copy, or redistribute it subject to the terms and conditions
@@ -450,6 +450,40 @@ out_uninit: }/** +* adjust_fs_space - Adjusts the free space available due to gfs2_grow +* @inode: the rindex inode +*/ +static void adjust_fs_space (struct inode *inode) +{ +struct gfs2_sbd *sdp = inode->i_sb->s_fs_info; +struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master; +struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; +__u64 fs_total, new_free, new_free_readable; +const char *stg_abbrev =" KMGTPEE" ; +int factor; + +/* Total up the file system space, according to the latest rindex. */ + fs_total =gfs2_ri_total (sdp); + +spin_lock (&sdp->sd_statfs_spin); +if (fs_total > (m_sc->sc_total + l_sc->sc_total)) + new_free = fs_total - (m_sc->sc_total + l_sc->sc_total); +else + new_free =0 ; +spin_unlock (&sdp->sd_statfs_spin); + new_free_readable = new_free * sdp->sd_sb.sb_bsize; +for (factor =0 ; factor <7 ; factor++) +if (new_free_readable >1024 ) + new_free_readable /=1024 ; +else +break ; +printk (KERN_WARNING "GFS2: File system extended by %llu " +"blocks (%llu%cB)\n" , new_free, new_free_readable, + stg_abbrev[factor]); +gfs2_statfs_change (sdp, new_free, new_free,0 ); +} + +/** * gfs2_commit_write - Commit write to a file * @file: The file to write to * @page: The page containing the data
@@ -511,6 +545,9 @@ static int gfs2_commit_write(struct file *file, struct page *page, di->di_size =cpu_to_be64 (inode->i_size); } +if (inode == sdp->sd_rindex) +adjust_fs_space (inode); +brelse (dibh);gfs2_trans_end (sdp);if (al->al_requested) {
fs/gfs2/ops_address.h +4 -1
@@ -1,6 +1,6 @@/* * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -* Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. +* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. * * This copyrighted material is made available to anyone wishing to use, * modify, copy, or redistribute it subject to the terms and conditions
@@ -18,5 +18,8 @@ extern const struct address_space_operations gfs2_file_aops;extern int gfs2_get_block (struct inode *inode,sector_t lblock,struct buffer_head *bh_result,int create);extern int gfs2_releasepage (struct page *page,gfp_t gfp_mask); +extern __u64 gfs2_ri_total (struct gfs2_sbd *sdp); +extern void gfs2_statfs_change (struct gfs2_sbd *sdp,s64 total,s64 free, +s64 dinodes);#endif /* __OPS_ADDRESS_DOT_H__ */
fs/gfs2/rgrp.c +87 -19
163 lines not on this page · raw message
PATCH 1/1 GFS2: kernel changes to support new gfs2_grow command (Try 3)
fs/gfs2/ops_address.c out_uninit: · line 461
Quoted 1 line · Robert Peterson
fs/gfs2/ops_address.c +1
-0+__u64 fs_total, new_free, new_free_readable;
use u64, __u64 is for structs shared with user space
fs/gfs2/ops_address.c out_uninit: · line 482
Quoted 3 lines
fs/gfs2/ops_address.c +3
-0+printk (KERN_WARNING "GFS2: File system extended by %llu " +"blocks (%llu%cB)\n" , new_free, new_free_readable, + stg_abbrev[factor]);
use fs_warn(), and unless there's some precedent elsewhere I don't think the human-readable translation is appropriate in the kernel.
fs/gfs2/rgrp.c static int gfs2_ri_update(struct gfs2_inode *ip) · line 486
Quoted 2 lines
fs/gfs2/rgrp.c +2
-0+ if (!gfs2_glock_is_held_excl(ip->i_gl) && + !gfs2_glock_is_held_shrd(ip->i_gl) &&
Be extremely wary of using these "is_held" functions algorithmically; needing to use them is usually an indication that you're doing something wrong (I'll have to study this case a bit more to say anything helpful).
It's instructional to note that the glock_is_held functions are _never_ used outside of assertions in all of gfs1 and gfs2! There's an exception to every rule, but...
Dave
PATCH 1/1 GFS2: kernel changes to support new gfs2_grow command (Try 3)
Quoted 4 lines · David Teigland
fs/gfs2/ops_address.c out_uninit: · line 461
Quoted 1 line · Robert Peterson
fs/gfs2/ops_address.c +1
-0+__u64 fs_total, new_free, new_free_readable;use u64,
__u64is for structs shared with user space
Okay.
Quoted 6 lines
fs/gfs2/ops_address.c out_uninit: · line 482
Quoted 3 lines
fs/gfs2/ops_address.c +3
-0+printk (KERN_WARNING "GFS2: File system extended by %llu " +"blocks (%llu%cB)\n" , new_free, new_free_readable, + stg_abbrev[factor]);use
fs_warn(), and unless there's some precedent elsewhere I don't think the human-readable translation is appropriate in the kernel.
Okay.
Quoted 6 lines
fs/gfs2/rgrp.c static int gfs2_ri_update(struct gfs2_inode *ip) · line 486
Quoted 2 lines
fs/gfs2/rgrp.c +2
-0+ if (!gfs2_glock_is_held_excl(ip->i_gl) && + !gfs2_glock_is_held_shrd(ip->i_gl) &&Be extremely wary of using these "
is_held" functions algorithmically; needing to use them is usually an indication that you're doing something wrong (I'll have to study this case a bit more to say anything helpful).
I was using these functions to determine if someone was doing writes to the rindex file through the meta_fs, in which case I don't want to exit with a consistency error. If the rindex is being written to, there may be partial pieces of rindex entries left on a page (i.e. between two gfs2_write_commits) before the writing is over. In these cases, it's normal and we should ignore the partial entries (and re-read them when the writing is complete and the version number has changed).
My concern here is if a different node decides to do an ri_update while a gfs2_grow is happening. For example, if someone does a mount of the file system on a different node, the rindex may briefly be in an inconsistent state.
Quoted 3 lines
It's instructional to note that the
glock_is_heldfunctions are _never_ used outside of assertions in all of gfs1 and gfs2! There's an exception to every rule, but...
Yeah, I noticed that.
Quoted 1 line
Dave
Bob Peterson
Red Hat Cluster Suite
PATCH 1/1 GFS2: kernel changes to support new gfs2_grow command (Try 3)
Quoted 16 lines · Robert Peterson
Quoted 6 lines
fs/gfs2/rgrp.c static int gfs2_ri_update(struct gfs2_inode *ip) · line 486
Quoted 2 lines
fs/gfs2/rgrp.c +2
-0+ if (!gfs2_glock_is_held_excl(ip->i_gl) && + !gfs2_glock_is_held_shrd(ip->i_gl) &&Be extremely wary of using these "
is_held" functions algorithmically; needing to use them is usually an indication that you're doing something wrong (I'll have to study this case a bit more to say anything helpful).I was using these functions to determine if someone was doing writes to the rindex file through the
meta_fs, in which case I don't want to exit with a consistency error. If the rindex is being written to, there may be partial pieces of rindex entries left on a page (i.e. between twogfs2_write_commits) before the writing is over. In these cases, it's normal and we should ignore the partial entries (and re-read them when the writing is complete and the version number has changed).
Quoted 4 lines
My concern here is if a different node decides to do an
ri_updatewhile agfs2_growis happening. For example, if someone does a mount of the file system on a different node, the rindex may briefly be in an inconsistent state.
Why doesn't the exclusive glock held over the update protect against other processes reading something bad?
Dave
PATCH 1/1 GFS2: kernel changes to support new gfs2_grow command (Try 3)
In reply to Robert PetersonQuoted 7 lines · Robert Peterson
*
gfs2_ri_update- Pull in a new resource index from the disk
* @gl: The glock covering the rindex inode
*fs/gfs2/rgrp.c +0
-0@@ -447,7 +479,12 @@ static int gfs2_ri_update(struct gfs2_inode *ip)u64 junk = ip->i_di.di_size;int error;
fs/gfs2/rgrp.c static int gfs2_ri_update(struct gfs2_inode *ip) · line 490
Quoted 10 lines
fs/gfs2/rgrp.c +6
-1-if (do_div (junk,sizeof (struct gfs2_rindex ))) { +/* If someone is holding the rindex file with a glock, they must +be updating it, in which case we may have partial entries. +In this case, we ignore the partials. */ +if (!gfs2_glock_is_held_excl (ip->i_gl) && + !gfs2_glock_is_held_shrd (ip->i_gl) && +do_div (junk,sizeof (struct gfs2_rindex ))) {gfs2_consist_inode (ip);return -EIO ; }
So the use of glock_is_held _is_ part of an assertion, not part of an algorithm which I was worried about before. We should only ever get to this spot with a shared glock, right? (rindex_hold takes it). So a plain old assertion that the glock is shared at the beginning would be ok, but this particular check doesn't make sense to me.
fs/gfs2/rgrp.c static int gfs2_ri_update(struct gfs2_inode *ip) · line 499
Quoted 7 lines
fs/gfs2/rgrp.c +3
-0@@ -457,6 +494,9 @@ static int gfs2_ri_update(struct gfs2_inode *ip)file_ra_state_init (&ra_state, inode->i_mapping);for (sdp->sd_rgrps =0 ;; sdp->sd_rgrps++) {loff_t pos = sdp->sd_rgrps *sizeof (struct gfs2_rindex ); + +if (pos +sizeof (struct gfs2_rindex ) >= ip->i_di.di_size) +break ;
Why is this needed now if it wasn't before?
fs/gfs2/rgrp.c static int gfs2_ri_update(struct gfs2_inode *ip) · line 502
Quoted 3 lines
fs/gfs2/rgrp.c +0
-0error =gfs2_internal_read (ip, &ra_state, buf, &pos,sizeof (struct gfs2_rindex ));if (!error)
Dave
PATCH 1/1 GFS2: kernel changes to support new gfs2_grow command (Try 3)
Quoted 5 lines · David Teigland
So the use of
glock_is_held_is_ part of an assertion, not part of an algorithm which I was worried about before. We should only ever get to this spot with a shared glock, right? (rindex_holdtakes it). So a plain old assertion that the glock is shared at the beginning would be ok, but this particular check doesn't make sense to me.
See previous email.
Quoted 1 line
Why is this needed now if it wasn't before?
Again, this goes back to the partial rinedx entries left on a page in the middle of an rindex update through the meta_fs. We don't want to read in a partial entry, we want to ignore it.
Regards,
Bob Peterson
Red Hat Cluster Suite
PATCH 1/1 GFS2: kernel changes to support new gfs2_grow command (Try 3)
In reply to David TeiglandQuoted 5 lines · David Teigland
Quoted 4 lines · Robert Peterson
fs/gfs2/rgrp.c +0
-0@@ -447,7 +479,12 @@ static int gfs2_ri_update(struct gfs2_inode *ip)u64 junk = ip->i_di.di_size;int error;
Quoted 16 lines
fs/gfs2/rgrp.c static int gfs2_ri_update(struct gfs2_inode *ip) · line 490
Quoted 10 lines
fs/gfs2/rgrp.c +6
-1-if (do_div (junk,sizeof (struct gfs2_rindex ))) { +/* If someone is holding the rindex file with a glock, they must +be updating it, in which case we may have partial entries. +In this case, we ignore the partials. */ +if (!gfs2_glock_is_held_excl (ip->i_gl) && + !gfs2_glock_is_held_shrd (ip->i_gl) && +do_div (junk,sizeof (struct gfs2_rindex ))) {gfs2_consist_inode (ip);return -EIO ; }So the use of
glock_is_held_is_ part of an assertion, not part of an algorithm which I was worried about before. We should only ever get to this spot with a shared glock, right? (rindex_holdtakes it). So a plain old assertion that the glock is shared at the beginning would be ok, but this particular check doesn't make sense to me.
For the sake of completeness, I retested without this change to make sure it was also still necessary. It was. The problem is that we can now call gfs2_ri_update while there are still partial rindex entries. This can happen when we need to allocate a new page to the rindex, which calls gfs2_inplace_reserve_i, which eventually gets to gfs2_check_rindex_version. Without the change, you get:
GFS2: fsid=bob_cluster2:test_gfs.0: fatal: filesystem consistency error
GFS2: fsid=bob_cluster2:test_gfs.0: inode = 19 25439
GFS2: fsid=bob_cluster2:test_gfs.0: function = gfs2_ri_update, file = fs/gfs2/rgrp.c, line = 486
GFS2: fsid=bob_cluster2:test_gfs.0: about to withdraw this file system
GFS2: fsid=bob_cluster2:test_gfs.0: telling LM to withdraw
GFS2: fsid=bob_cluster2:test_gfs.0: withdrawn
[<e02a5c2f>] gfs2_lm_withdraw+0x82/0x8d [gfs2] [<e02b72d0>] gfs2_consist_inode_i+0x6f/0x75 [gfs2] [<e02b34da>] gfs2_check_rindex_version+0x11e/0x468 [gfs2] [<c04078a5>] __sched_text_start+0x715/0x7c4 [<e029a335>] gfs2_extent_map+0x68/0x9c [gfs2] [<e02b3dbb>] gfs2_inplace_reserve_i+0x9a/0x443 [gfs2] [<e029a4fb>] gfs2_write_alloc_required+0x192/0x1ce [gfs2] [<e02aad58>] gfs2_prepare_write+0x12d/0x237 [gfs2] [<e02aac2b>] gfs2_prepare_write+0x0/0x237 [gfs2] [<c0138422>] generic_file_buffered_write+0x25b/0x60f [<c03b6594>] tcp_v4_do_rcv+0x28/0x307 [<c016857e>] __mark_inode_dirty+0xdd/0x15c [<c011dbb6>] current_fs_time+0x41/0x46 [<c0138cbd>] __generic_file_aio_write_nolock+0x4e7/0x560 [<c013afef>] get_page_from_freelist+0x24f/0x2cf [<c0138d8b>] generic_file_aio_write+0x55/0xb3 [<c01514cd>] do_sync_write+0xc7/0x10a [<e02a3293>] gfs2_holder_uninit+0xb/0x1b [gfs2] [<c01296cd>] autoremove_wake_function+0x0/0x35 [<e02a3293>] gfs2_holder_uninit+0xb/0x1b [gfs2] [<e02ac3d8>] gfs2_llseek+0x76/0x9a [gfs2] [<c0151406>] do_sync_write+0x0/0x10a [<c0151c30>] vfs_write+0x8a/0x10c [<c015219f>] sys_write+0x41/0x67 [<c01030d8>] sysenter_past_esp+0x5d/0x81 [<c0400000>] svc_defer+0x6b/0x126 =======================
Quoted 9 lines
fs/gfs2/rgrp.c static int gfs2_ri_update(struct gfs2_inode *ip) · line 499
Quoted 7 lines
fs/gfs2/rgrp.c +3
-0@@ -457,6 +494,9 @@ static int gfs2_ri_update(struct gfs2_inode *ip)file_ra_state_init (&ra_state, inode->i_mapping);for (sdp->sd_rgrps =0 ;; sdp->sd_rgrps++) {loff_t pos = sdp->sd_rgrps *sizeof (struct gfs2_rindex ); + +if (pos +sizeof (struct gfs2_rindex ) >= ip->i_di.di_size) +break ;Why is this needed now if it wasn't before?
For the same reason as the above check is necessary.
Regards,
Bob Peterson
Red Hat Cluster Suite
PATCH 1/1 GFS2: kernel changes to support new gfs2_grow command (Try 3)
In reply to Robert Petersonfs/gfs2/rgrp.c int gfs2_inplace_reserve_i(struct gfs2_inode *ip, · line 1045
Quoted 10 lines · Robert Peterson
fs/gfs2/rgrp.c +7
-1@@ -978,18 +1038,25 @@ int gfs2_inplace_reserve_i(struct gfs2_inode *ip, - error =gfs2_rindex_hold (sdp, &al->al_ri_gh); +/* We need to hold the rindex unless the inode we're using is +the rindex itself, in which case it's already held. */ +if (ip !=GFS2_I (sdp->sd_rindex)) + error =gfs2_rindex_hold (sdp, &al->al_ri_gh); +else if (!sdp->sd_rgrps)/* We may not have the rindex read in, so: */ + error =gfs2_check_rindex_version (sdp); +
I don't see why we need this change, the original looks correct.
So there are the two distinct parts to the fs-grow procedure. The first is writing to the rindex and statfs files -- this is what was missing in gfs2, and I'm ignoring that part for now.
The second part is gfs detecting that a grow took place and updating its list of rg's. I don't think this part needs any changing at all, it should work the same way it always has -- this is what I'm focussing on.
Dave
PATCH 1/1 GFS2: kernel changes to support new gfs2_grow command (Try 3)
Quoted 13 lines · David Teigland
fs/gfs2/rgrp.c int gfs2_inplace_reserve_i(struct gfs2_inode *ip, · line 1045
Quoted 10 lines · Robert Peterson
fs/gfs2/rgrp.c +7
-1@@ -978,18 +1038,25 @@ int gfs2_inplace_reserve_i(struct gfs2_inode *ip, - error =gfs2_rindex_hold (sdp, &al->al_ri_gh); +/* We need to hold the rindex unless the inode we're using is +the rindex itself, in which case it's already held. */ +if (ip !=GFS2_I (sdp->sd_rindex)) + error =gfs2_rindex_hold (sdp, &al->al_ri_gh); +else if (!sdp->sd_rgrps)/* We may not have the rindex read in, so: */ + error =gfs2_check_rindex_version (sdp); +I don't see why we need this change, the original looks correct.
If we're updating through the meta_fs, the rindex file will already be glocked and held through its inode.
Quoted 7 lines
So there are the two distinct parts to the fs-grow procedure. The first is writing to the rindex and statfs files -- this is what was missing in gfs2, and I'm ignoring that part for now.
The second part is gfs detecting that a grow took place and updating its list of rg's. I don't think this part needs any changing at all, it should work the same way it always has -- this is what I'm focussing on.
I'll re-test test the original code path to make sure that this part of the fix is still really necessary.
Regards,
Bob Peterson
Red Hat Cluster Suite
PATCH 1/1 GFS2: kernel changes to support new gfs2_grow command (Try 3)
Quoted 16 lines · Robert Peterson
Quoted 14 lines · David Teigland
fs/gfs2/rgrp.c int gfs2_inplace_reserve_i(struct gfs2_inode *ip, · line 1046
Quoted 11 lines · Robert Peterson
fs/gfs2/rgrp.c +7
-1@@ -978,18 +1038,25 @@ int gfs2_inplace_reserve_i(struct gfs2_inode *ip, -error = gfs2_rindex_hold(sdp, &al->al_ri_gh); +/* We need to hold the rindex unless the inode we're using is +the rindex itself, in which case it's already held. */ +if (ip !=GFS2_I (sdp->sd_rindex)) + error =gfs2_rindex_hold (sdp, &al->al_ri_gh); +else if (!sdp->sd_rgrps)/* We may not have the rindex read in, so: */ + error =gfs2_check_rindex_version (sdp); +I don't see why we need this change, the original looks correct.
Quoted 2 lines
If we're updating through the
meta_fs, the rindex file will already be glocked and held through its inode.
You don't have to worry about other holders or the state of the glock, just let gfs_rindex_hold() enqueue its own shared holder and everything should work fine.
PATCH 1/1 GFS2: kernel changes to support new gfs2_grow command (Try 3)
In reply to Robert PetersonQuoted 27 lines · Robert Peterson
Quoted 13 lines · David Teigland
fs/gfs2/rgrp.c int gfs2_inplace_reserve_i(struct gfs2_inode *ip, char *file, unsigned int line) · line 1052
Quoted 11 lines · Robert Peterson
fs/gfs2/rgrp.c +5
-1@@ -978,18 +1038,25 @@ int gfs2_inplace_reserve_i(struct gfs2_inode *ip, - error =gfs2_rindex_hold (sdp, &al->al_ri_gh); +/* We need to hold the rindex unless the inode we're using is +the rindex itself, in which case it's already held. */ +if (ip !=GFS2_I (sdp->sd_rindex)) + error =gfs2_rindex_hold (sdp, &al->al_ri_gh); +else if (!sdp->sd_rgrps)/* We may not have the rindex read in, so: */
fs/gfs2/rgrp.c +2
-0+ error =gfs2_check_rindex_version (sdp); +Quoted 1 line
I don't see why we need this change, the original looks correct.
If we're updating through the
meta_fs, the rindex file will already be glocked and held through its inode.Quoted 7 lines
So there are the two distinct parts to the fs-grow procedure. The first is writing to the rindex and statfs files -- this is what was missing in gfs2, and I'm ignoring that part for now.
The second part is gfs detecting that a grow took place and updating its list of rg's. I don't think this part needs any changing at all, it should work the same way it always has -- this is what I'm focussing on.
Quoted 8 lines
I'll re-test test the original code path to make sure that this part of the fix is still really necessary.
Regards,
Bob Peterson
Red Hat Cluster Suite
Hi Dave,
Well, I retested this code path and found that this code is still necessary (unless I should somehow be doing this a different way). Without the code, the gfs2_rindex_hold tries to add a holder, but there's already a holder due to the meta_fs. Under the right conditions, you get:
original: gfs2_prepare_write+0x49/0x237 [gfs2]
new: gfs2_rindex_hold+0x2b/0x52a [gfs2]
------------[ cut here ]------------ kernel BUG at fs/gfs2/glock.c:1057! invalid opcode: 0000 [#1] SMP Modules linked in: lock_dlm gfs2 dlm configfs sd_mod sg qla2xxx CPU: 0 EIP: 0060:[<e02a2fd3>] Not tainted VLI EFLAGS: 00010282 (2.6.21 #2)
EIP is at gfs2_glock_nq+0xff/0x1a6 [gfs2]
eax: 00000020 ebx: c3070b54 ecx: 00000046 edx: 00000046
esi: c3070c2c edi: d5147b1c ebp: d5147b1c esp: d18f7bf0
ds: 007b es: 007b fs: 00d8 gs: 0033 ss: 0068
Process gfs2_grow (pid: 5762, ti=d18f6000 task=df6e9ab0 task.ti=d18f6000)
Stack: e02b8e4e 00000002 00000001 c8ba1000 00000000 c8ba1000 00000000 c8ba1000
c307099c e02b33f0 c3070c2c 00000000 d5147b1c c3070c98 def5eeb8 d521d108
00001000 c3070c2c d18f7c6c c307099c d18f7cbc e029a2c1 d18f7c6c 00000000
Call Trace:
[<e02b33f0>] gfs2_rindex_hold+0x34/0x52a [gfs2]
[<e029a2c1>] gfs2_block_map+0x39f/0x3ab [gfs2]
[<c04078a5>] __sched_text_start+0x715/0x7c4
[<e029a335>] gfs2_extent_map+0x68/0x9c [gfs2]
[<e02b3e08>] gfs2_inplace_reserve_i+0x7b/0x418 [gfs2]
[<e029a4fb>] gfs2_write_alloc_required+0x192/0x1ce [gfs2]
[<e02aad58>] gfs2_prepare_write+0x12d/0x237 [gfs2]
[<e02aac2b>] gfs2_prepare_write+0x0/0x237 [gfs2]
[<c0138422>] generic_file_buffered_write+0x25b/0x60f
[<c016857e>] __mark_inode_dirty+0xdd/0x15c
[<c011dbb6>] current_fs_time+0x41/0x46
[<c0138cbd>] __generic_file_aio_write_nolock+0x4e7/0x560
[<c013afef>] get_page_from_freelist+0x24f/0x2cf
[<c0138d8b>] generic_file_aio_write+0x55/0xb3
[<c01514cd>] do_sync_write+0xc7/0x10a
[<e02a3293>] gfs2_holder_uninit+0xb/0x1b [gfs2]
[<c01296cd>] autoremove_wake_function+0x0/0x35
[<e02a3293>] gfs2_holder_uninit+0xb/0x1b [gfs2]
[<e02ac3d8>] gfs2_llseek+0x76/0x9a [gfs2]
[<c0151406>] do_sync_write+0x0/0x10a
[<c0151c30>] vfs_write+0x8a/0x10c
[<c015219f>] sys_write+0x41/0x67
[<c01030d8>] sysenter_past_esp+0x5d/0x81
[<c0400000>] svc_defer+0x6b/0x126
=======================Regards,
Bob Peterson
Red Hat Cluster Suite
PATCH 1/1 GFS2: kernel changes to support new gfs2_grow command (Try 3)
Hi,
Quoted 38 lines · Robert Peterson
Quoted 27 lines · Robert Peterson
Quoted 13 lines · David Teigland
fs/gfs2/rgrp.c int gfs2_inplace_reserve_i(struct gfs2_inode *ip, char *file, unsigned int line) · line 1052
Quoted 11 lines · Robert Peterson
fs/gfs2/rgrp.c +5
-1@@ -978,18 +1038,25 @@ int gfs2_inplace_reserve_i(struct gfs2_inode *ip, - error =gfs2_rindex_hold (sdp, &al->al_ri_gh); +/* We need to hold the rindex unless the inode we're using is +the rindex itself, in which case it's already held. */ +if (ip !=GFS2_I (sdp->sd_rindex)) + error =gfs2_rindex_hold (sdp, &al->al_ri_gh); +else if (!sdp->sd_rgrps)/* We may not have the rindex read in, so: */
fs/gfs2/rgrp.c +2
-0+ error =gfs2_check_rindex_version (sdp); +Quoted 1 line
I don't see why we need this change, the original looks correct.
If we're updating through the
meta_fs, the rindex file will already be glocked and held through its inode.Quoted 7 lines
So there are the two distinct parts to the fs-grow procedure. The first is writing to the rindex and statfs files -- this is what was missing in gfs2, and I'm ignoring that part for now.
The second part is gfs detecting that a grow took place and updating its list of rg's. I don't think this part needs any changing at all, it should work the same way it always has -- this is what I'm focussing on.
Quoted 8 lines
I'll re-test test the original code path to make sure that this part of the fix is still really necessary.
Regards,
Bob Peterson
Red Hat Cluster SuiteHi Dave,
Quoted 8 lines
Well, I retested this code path and found that this code is still necessary (unless I should somehow be doing this a different way). Without the code, the
gfs2_rindex_holdtries to add a holder, but there's already a holder due to themeta_fs. Under the right conditions, you get:original:
gfs2_prepare_write+0x49/0x237[gfs2]
new:gfs2_rindex_hold+0x2b/0x52a[gfs2]
I agree that this change is needed, its how we've solved the same problem elsewhere and it looks ok to me,
Steve.