public inbox for linux-nfs@vger.kernel.org
 help / color / mirror / Atom feed
From: Ben Myers <bpm@sgi.com>
To: linux-nfs@vger.kernel.org
Subject: [RFC PATCH 2/2] xfs_export_operations.commit_metadata
Date: Tue, 09 Feb 2010 18:33:37 -0600	[thread overview]
Message-ID: <20100210003337.6021.10942.stgit@case> (raw)
In-Reply-To: <20100210003220.6021.74943.stgit@case>

Here is the commit_metadata export_operation for xfs.  We take two dentries and
force the log up to the larger lsn.  It looks to me that in nfsd the child is
always modified after the parent so generally we expect the child's lsn to be
larger.  If that's not the case we'll just force the entire thing.

The basic form of this is based upon one of Christoph's suggestions.  I'm an
xfs newbie so I'm not very comfortable with it yet.  My understanding is that I
need to verify that all of the necessary changes make it into the transations
we're forcing into the log here.  I am still looking into that and hopefully
the XFS gurus can continue to provide guidance.
---
 fs/xfs/linux-2.6/xfs_export.c |   64 +++++++++++++++++++++++++++++++++++++++++
 1 files changed, 64 insertions(+), 0 deletions(-)

diff --git a/fs/xfs/linux-2.6/xfs_export.c b/fs/xfs/linux-2.6/xfs_export.c
index 87b8cbd..af4a214 100644
--- a/fs/xfs/linux-2.6/xfs_export.c
+++ b/fs/xfs/linux-2.6/xfs_export.c
@@ -29,6 +29,7 @@
 #include "xfs_vnodeops.h"
 #include "xfs_bmap_btree.h"
 #include "xfs_inode.h"
+#include "xfs_inode_item.h"
 
 /*
  * Note that we only accept fileids which are long enough rather than allow
@@ -215,9 +216,72 @@ xfs_fs_get_parent(
 	return d_obtain_alias(VFS_I(cip));
 }
 
+STATIC int
+xfs_fs_nfs_commit_metadata(
+	struct dentry		*parent,
+	struct dentry		*child)
+{
+	struct xfs_inode	*p_xip = NULL, *c_xip = NULL;
+	struct xfs_mount	*i_mount = NULL;	
+	xfs_lsn_t		force_lsn = 0;
+	int 			error = 0;
+
+	if (parent && !child) {
+		p_xip = XFS_I(parent->d_inode);
+		xfs_ilock(p_xip, XFS_ILOCK_SHARED);
+		if (xfs_ipincount(p_xip)) {
+			force_lsn = p_xip->i_itemp->ili_last_lsn;
+			i_mount = p_xip->i_mount;
+		}
+	} else if (child && !parent) {
+		c_xip = XFS_I(child->d_inode);
+		xfs_ilock(c_xip, XFS_ILOCK_SHARED);
+		if (xfs_ipincount(c_xip)) {
+			force_lsn = c_xip->i_itemp->ili_last_lsn;
+			i_mount = c_xip->i_mount;
+		}
+	} else if (parent && child) {
+		p_xip = XFS_I(parent->d_inode);
+		c_xip = XFS_I(child->d_inode);
+		xfs_ilock(p_xip, XFS_ILOCK_SHARED);
+		xfs_ilock(c_xip, XFS_ILOCK_SHARED);
+		if (xfs_ipincount(p_xip)) {
+			force_lsn = p_xip->i_itemp->ili_last_lsn;
+			i_mount = p_xip->i_mount;
+		}
+		if (xfs_ipincount(c_xip)) {
+			/*
+			 * AFAICS the child is always modified after the parent
+			 * in nfsd so should always have a larger lsn.
+			 */
+			if (c_xip->i_itemp->ili_last_lsn > force_lsn) {
+				force_lsn = c_xip->i_itemp->ili_last_lsn;
+			} else {
+				force_lsn = 0; /* whole thing */
+			}
+			i_mount = c_xip->i_mount;
+		}
+	} else {
+		return -EINVAL;
+	}
+
+	if (i_mount) {
+		error = _xfs_log_force(i_mount, force_lsn,
+				XFS_LOG_FORCE | XFS_LOG_SYNC, NULL);
+	}
+
+	if (child)
+		xfs_iunlock(c_xip, XFS_ILOCK_SHARED);
+	if (parent)
+		xfs_iunlock(p_xip, XFS_ILOCK_SHARED);
+
+	return error;
+}
+
 const struct export_operations xfs_export_operations = {
 	.encode_fh		= xfs_fs_encode_fh,
 	.fh_to_dentry		= xfs_fs_fh_to_dentry,
 	.fh_to_parent		= xfs_fs_fh_to_parent,
 	.get_parent		= xfs_fs_get_parent,
+	.commit_metadata	= xfs_fs_nfs_commit_metadata,
 };


  parent reply	other threads:[~2010-02-10  0:33 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-02-10  0:33 [RFC PATCH 0/2] nfsd sync export_op (was 'wsync export option') Ben Myers
2010-02-10  0:33 ` [RFC PATCH 1/2] commit_metadata export operation and nfsd_sync2 Ben Myers
2010-02-10  8:56   ` Christoph Hellwig
2010-02-10 19:53     ` bpm
2010-02-10 21:56       ` Christoph Hellwig
2010-02-10  0:33 ` Ben Myers [this message]
2010-02-10  9:07   ` [RFC PATCH 2/2] xfs_export_operations.commit_metadata Christoph Hellwig
2010-02-10 10:11     ` Christoph Hellwig
2010-02-10 20:15     ` bpm
2010-02-10 21:29       ` Dave Chinner
2010-02-10 21:57       ` Christoph Hellwig

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=20100210003337.6021.10942.stgit@case \
    --to=bpm@sgi.com \
    --cc=linux-nfs@vger.kernel.org \
    /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