public inbox for linux-xfs@vger.kernel.org
 help / color / mirror / Atom feed
From: Lachlan McIlroy <lachlan@sgi.com>
To: David Chinner <dgc@sgi.com>
Cc: xfs-dev <xfs-dev@sgi.com>, xfs-oss <xfs@oss.sgi.com>
Subject: Re: [PATCH] make inode reclaim synchronise with xfs_iflush_done()
Date: Mon, 14 Jan 2008 14:57:04 +1100	[thread overview]
Message-ID: <478ADD90.1000806@sgi.com> (raw)
In-Reply-To: <20071212230858.GO4612@sgi.com>

David Chinner wrote:
> (can ppl please post patches in line rather than as attachments
> as it's really hard to quote attachments)
> 
> On Wed, Dec 12, 2007 at 06:02:37PM +1100, Lachlan McIlroy wrote:
>> On a forced shutdown, xfs_finish_reclaim() will skip flushing the inode.
>> If the inode flush lock is not already held and there is an outstanding
>> xfs_iflush_done() then we might free the inode prematurely.  By acquiring
>> and releasing the flush lock we will synchronise with xfs_iflush_done().
> 
> Yes, That could happen. Good catch. Comments on the code below.
> 
>> Alternatively we could take a hold on the inode when when issuing I/Os
>> with xfs_iflush_done() and release it in xfs_iflush_done().  Would this
>> be a better approach?
> 
> No - we can't take a hold on the inode because it may not have a linux
> inode attached to it and hence there's nothing to hold the reference
> count (we use the linux inode reference count for this).
> 
> 
> --- fs/xfs/xfs_vnodeops.c_1.726	2007-12-12 17:14:59.000000000 +1100
> +++ fs/xfs/xfs_vnodeops.c	2007-12-12 17:15:42.000000000 +1100
> @@ -3762,20 +3762,29 @@ xfs_finish_reclaim(
>  				goto reclaim;
>  			}
>  			xfs_iflock(ip); /* synchronize with xfs_iflush_done */
> +			xfs_ifunlock(ip);
>  		}
> 
> Why do you unlock it here? If it is left locked, there is absolutely
> no chance for the inode to be flushed again after this point.
>  
>  		ASSERT(ip->i_update_core == 0);
>  		ASSERT(ip->i_itemp == NULL ||
>  		       ip->i_itemp->ili_format.ilf_fields == 0);
>  		xfs_iunlock(ip, XFS_ILOCK_EXCL);
> -	} else if (locked) {
> +	} else {
>  		/*
>  		 * We are not interested in doing an iflush if we're
>  		 * in the process of shutting down the filesystem forcibly.
>  		 * So, just reclaim the inode.
> -		 */
> -		xfs_ifunlock(ip);
> -		xfs_iunlock(ip, XFS_ILOCK_EXCL);
> +		 * 
> +		 * If the flush lock is not already held then temporarily
> +		 * acquire it to synchronize with xfs_iflush_done.
> +		 */
> +		if (locked) {
> +			xfs_ifunlock(ip);
> +			xfs_iunlock(ip, XFS_ILOCK_EXCL);
> +		} else {
> +			xfs_iflock(ip);
> +			xfs_ifunlock(ip);
> +		}
>  	}
> 
> Oh, that just makes it messy :/
> 
> How about locking the inode unconditionally before the entire if..else
> statement like:
> 
> +	if (!locked) {
> +		xfs_ilock(ip, XFS_ILOCK_EXCL);
> +		xfs_iflock(ip);
> +	}
>         if (!XFS_FORCED_SHUTDOWN(ip->i_mount)) {
> -		if (!locked) {
> -			xfs_ilock(ip, XFS_ILOCK_EXCL);
> -			xfs_iflock(ip);
> -		}
> 
> .....
> -	} else if (locked) {
> +	} else {
>  		/*
>  		 * We are not interested in doing an iflush if we're
>  		 * in the process of shutting down the filesystem forcibly.
>  		 * So, just reclaim the inode.
> -		xfs_ifunlock(ip);
> 		xfs_iunlock(ip, XFS_ILOCK_EXCL);
>  	}
>   reclaim:
> 
> That would mean we always go to xfs_ireclaim() with the flush lock held
> and hence a guarantee that no more I/O can be issued on the inode.

That would be a bad thing.  We are about to tear the inode down and free
the memory.  If any threads are still waiting on the flush lock they will
wait forever or eventually access freed memory.

This patch cleans up the code a little further by removing the
'else if (locked)' case.

--- fs/xfs/xfs_vnodeops.c_1.727	2008-01-10 16:00:48.000000000 +1100
+++ fs/xfs/xfs_vnodeops.c	2008-01-11 13:35:41.000000000 +1100
@@ -3721,12 +3721,12 @@ xfs_finish_reclaim(
  	 * We get the flush lock regardless, though, just to make sure
  	 * we don't free it while it is being flushed.
  	 */
-	if (!XFS_FORCED_SHUTDOWN(ip->i_mount)) {
-		if (!locked) {
-			xfs_ilock(ip, XFS_ILOCK_EXCL);
-			xfs_iflock(ip);
-		}
+	if (!locked) {
+		xfs_ilock(ip, XFS_ILOCK_EXCL);
+		xfs_iflock(ip);
+	}

+	if (!XFS_FORCED_SHUTDOWN(ip->i_mount)) {
  		if (ip->i_update_core ||
  		    ((ip->i_itemp != NULL) &&
  		     (ip->i_itemp->ili_format.ilf_fields != 0))) {
@@ -3746,18 +3746,12 @@ xfs_finish_reclaim(
  		ASSERT(ip->i_update_core == 0);
  		ASSERT(ip->i_itemp == NULL ||
  		       ip->i_itemp->ili_format.ilf_fields == 0);
-		xfs_iunlock(ip, XFS_ILOCK_EXCL);
-	} else if (locked) {
-		/*
-		 * We are not interested in doing an iflush if we're
-		 * in the process of shutting down the filesystem forcibly.
-		 * So, just reclaim the inode.
-		 */
-		xfs_ifunlock(ip);
-		xfs_iunlock(ip, XFS_ILOCK_EXCL);
  	}

- reclaim:
+	xfs_ifunlock(ip);
+	xfs_iunlock(ip, XFS_ILOCK_EXCL);
+
+reclaim:
  	xfs_ireclaim(ip);
  	return 0;
  }

      parent reply	other threads:[~2008-01-14  3:54 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-12-12  7:02 [PATCH] make inode reclaim synchronise with xfs_iflush_done() Lachlan McIlroy
2007-12-14 20:29 ` Christoph Hellwig
     [not found] ` <20071212230858.GO4612@sgi.com>
2008-01-14  3:57   ` Lachlan McIlroy [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=478ADD90.1000806@sgi.com \
    --to=lachlan@sgi.com \
    --cc=dgc@sgi.com \
    --cc=xfs-dev@sgi.com \
    --cc=xfs@oss.sgi.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox