From: Steven Whitehouse <swhiteho@redhat.com>
To: cluster-devel.redhat.com
Subject: [Cluster-devel] [GFS2 Patch] GFS2: stuck in inode wait, no glocks stuck
Date: Wed, 12 May 2010 10:30:36 +0100 [thread overview]
Message-ID: <1273656636.2884.27.camel@localhost> (raw)
In-Reply-To: <210534934.573371273615091851.JavaMail.root@zmail06.collab.prod.int.phx2.redhat.com>
Hi,
Now in the -nmw git tree. Thanks,
Steve.
On Tue, 2010-05-11 at 17:58 -0400, Bob Peterson wrote:
> Hi,
>
> This patch changes the lock ordering when gfs2 reclaims
> unlinked dinodes, thereby avoiding a livelock.
>
> Regards,
>
> Bob Peterson
> Red Hat GFS
>
> Signed-off-by: Bob Peterson <rpeterso@redhat.com>
> --
> GFS2: stuck in inode wait, no glocks stuck
>
> This patch changes the lock ordering when gfs2 reclaims
> unlinked dinodes, thereby avoiding a livelock.
>
> rhbz#583737
>
> diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
> index 3739155..8bce73e 100644
> --- a/fs/gfs2/rgrp.c
> +++ b/fs/gfs2/rgrp.c
> @@ -952,16 +952,14 @@ static int try_rgrp_fit(struct gfs2_rgrpd *rgd, struct gfs2_alloc *al)
> * The inode, if one has been found, in inode.
> */
>
> -static int try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked,
> - u64 skip, struct inode **inode)
> +static u64 try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked,
> + u64 skip)
> {
> u32 goal = 0, block;
> u64 no_addr;
> struct gfs2_sbd *sdp = rgd->rd_sbd;
> unsigned int n;
> - int error = 0;
>
> - *inode = NULL;
> for(;;) {
> if (goal >= rgd->rd_data)
> break;
> @@ -981,10 +979,7 @@ static int try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked,
> if (no_addr == skip)
> continue;
> *last_unlinked = no_addr;
> - error = gfs2_unlinked_inode_lookup(rgd->rd_sbd->sd_vfs,
> - no_addr, inode);
> - if (*inode || error)
> - return error;
> + return no_addr;
> }
>
> rgd->rd_flags &= ~GFS2_RDF_CHECK;
> @@ -1069,11 +1064,12 @@ static void forward_rgrp_set(struct gfs2_sbd *sdp, struct gfs2_rgrpd *rgd)
> * Try to acquire rgrp in way which avoids contending with others.
> *
> * Returns: errno
> + * unlinked: the block address of an unlinked block to be reclaimed
> */
>
> -static struct inode *get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked)
> +static int get_local_rgrp(struct gfs2_inode *ip, u64 *unlinked,
> + u64 *last_unlinked)
> {
> - struct inode *inode = NULL;
> struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
> struct gfs2_rgrpd *rgd, *begin = NULL;
> struct gfs2_alloc *al = ip->i_alloc;
> @@ -1082,6 +1078,7 @@ static struct inode *get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked)
> int loops = 0;
> int error, rg_locked;
>
> + *unlinked = 0;
> rgd = gfs2_blk2rgrpd(sdp, ip->i_goal);
>
> while (rgd) {
> @@ -1103,29 +1100,19 @@ static struct inode *get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked)
> because that would require an iput which can only
> happen after the rgrp is unlocked. */
> if (!rg_locked && rgd->rd_flags & GFS2_RDF_CHECK)
> - error = try_rgrp_unlink(rgd, last_unlinked,
> - ip->i_no_addr, &inode);
> + *unlinked = try_rgrp_unlink(rgd, last_unlinked,
> + ip->i_no_addr);
> if (!rg_locked)
> gfs2_glock_dq_uninit(&al->al_rgd_gh);
> - if (inode) {
> - if (error) {
> - if (inode->i_state & I_NEW)
> - iget_failed(inode);
> - else
> - iput(inode);
> - return ERR_PTR(error);
> - }
> - return inode;
> - }
> - if (error)
> - return ERR_PTR(error);
> + if (*unlinked)
> + return -EAGAIN;
> /* fall through */
> case GLR_TRYFAILED:
> rgd = recent_rgrp_next(rgd);
> break;
>
> default:
> - return ERR_PTR(error);
> + return error;
> }
> }
>
> @@ -1148,22 +1135,12 @@ static struct inode *get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked)
> if (try_rgrp_fit(rgd, al))
> goto out;
> if (!rg_locked && rgd->rd_flags & GFS2_RDF_CHECK)
> - error = try_rgrp_unlink(rgd, last_unlinked,
> - ip->i_no_addr, &inode);
> + *unlinked = try_rgrp_unlink(rgd, last_unlinked,
> + ip->i_no_addr);
> if (!rg_locked)
> gfs2_glock_dq_uninit(&al->al_rgd_gh);
> - if (inode) {
> - if (error) {
> - if (inode->i_state & I_NEW)
> - iget_failed(inode);
> - else
> - iput(inode);
> - return ERR_PTR(error);
> - }
> - return inode;
> - }
> - if (error)
> - return ERR_PTR(error);
> + if (*unlinked)
> + return -EAGAIN;
> break;
>
> case GLR_TRYFAILED:
> @@ -1171,7 +1148,7 @@ static struct inode *get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked)
> break;
>
> default:
> - return ERR_PTR(error);
> + return error;
> }
>
> rgd = gfs2_rgrpd_get_next(rgd);
> @@ -1180,7 +1157,7 @@ static struct inode *get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked)
>
> if (rgd == begin) {
> if (++loops >= 3)
> - return ERR_PTR(-ENOSPC);
> + return -ENOSPC;
> if (!skipped)
> loops++;
> flags = 0;
> @@ -1200,7 +1177,7 @@ out:
> forward_rgrp_set(sdp, rgd);
> }
>
> - return NULL;
> + return 0;
> }
>
> /**
> @@ -1216,7 +1193,7 @@ int gfs2_inplace_reserve_i(struct gfs2_inode *ip, char *file, unsigned int line)
> struct gfs2_alloc *al = ip->i_alloc;
> struct inode *inode;
> int error = 0;
> - u64 last_unlinked = NO_BLOCK;
> + u64 last_unlinked = NO_BLOCK, unlinked;
>
> if (gfs2_assert_warn(sdp, al->al_requested))
> return -EINVAL;
> @@ -1232,14 +1209,19 @@ try_again:
> if (error)
> return error;
>
> - inode = get_local_rgrp(ip, &last_unlinked);
> - if (inode) {
> + error = get_local_rgrp(ip, &unlinked, &last_unlinked);
> + if (error) {
> if (ip != GFS2_I(sdp->sd_rindex))
> gfs2_glock_dq_uninit(&al->al_ri_gh);
> - if (IS_ERR(inode))
> - return PTR_ERR(inode);
> - iput(inode);
> + if (error != -EAGAIN)
> + return error;
> + error = gfs2_unlinked_inode_lookup(ip->i_inode.i_sb,
> + unlinked, &inode);
> + if (inode)
> + iput(inode);
> gfs2_log_flush(sdp, NULL);
> + if (error == GLR_TRYFAILED)
> + error = 0;
> goto try_again;
> }
>
prev parent reply other threads:[~2010-05-12 9:30 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <138792730.573041273614686623.JavaMail.root@zmail06.collab.prod.int.phx2.redhat.com>
2010-05-11 21:58 ` [Cluster-devel] [GFS2 Patch] GFS2: stuck in inode wait, no glocks stuck Bob Peterson
2010-05-12 9:30 ` Steven Whitehouse [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1273656636.2884.27.camel@localhost \
--to=swhiteho@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.