[pnfs] [PATCH 7/9] layoutrecall: send final layout return

Benny Halevy bhalevy at panasas.com
Thu Aug 30 09:33:20 EDT 2007


each layout recall must be terminated with a corresponding
layoutreturn that echoes the layoutrecall recall_type, iomode
and recall_type specific arguments (offset, length, and fsid
correspondingly).

In the RECALL_FILE case, pnfs_return_layout()
is doing the right thing and returns the recalled iomode and
byte range.  In the RECALL_{FSID,ALL} cases we keep a reference
to the last inode we used and use to to send the final layoutreturn
RPC to the server.  It is a bug not to find such inode as we
should have return the NOMATCHING_LAYOUT error in this case.

Note that the PUT_FH in the RETURN_ALL case is extraneous

Signed-off-by: Benny Halevy <bhalevy at panasas.com>
---
 fs/nfs/delegation.c |   32 +++++++++++++++++++++++++++-----
 1 files changed, 27 insertions(+), 5 deletions(-)

diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
index db43b6e..e6a909a 100644
--- a/fs/nfs/delegation.c
+++ b/fs/nfs/delegation.c
@@ -14,6 +14,7 @@
 
 #include <linux/nfs4.h>
 #include <linux/nfs_fs.h>
+#include <linux/nfs4_pnfs.h>
 #include <linux/nfs_xdr.h>
 #include <linux/writeback.h>
 
@@ -361,11 +362,13 @@ static int recall_thread(void *data)
 
 static int recall_layout_thread(void *data)
 {
-	struct inode *inode;
+	struct inode *inode = NULL;
 	struct nfs4_client *clp;
-	struct nfs_server *server= NULL;
+	struct nfs_server *server = NULL;
 	struct super_block *sb = NULL;
 	struct recall_layout_threadargs *args = (struct recall_layout_threadargs *)data;
+	struct nfs4_pnfs_layoutreturn_arg lr_arg;
+	int status;
 	int found = 0;
 
 	daemonize("nfsv4-layoutreturn");
@@ -401,10 +404,12 @@ static int recall_layout_thread(void *data)
 				continue;
 			/* XXX UGLY UGLY hack alert! */
 			do {
+				struct inode *ino;
+
 				found = 0;
 				spin_lock(&inode_lock);
-				list_for_each_entry(inode, &sb->s_inodes, i_sb_list) {
-					if (NFS_I(inode)->current_layout) {
+				list_for_each_entry(ino, &sb->s_inodes, i_sb_list) {
+					if (NFS_I(ino)->current_layout) {
 						found = 1;
 						break;
 					}
@@ -412,15 +417,32 @@ static int recall_layout_thread(void *data)
 				spin_unlock(&inode_lock);
 
 				if (found) {
+					if (inode)
+						iput(inode);
+					inode = ino;
 					igrab(inode);
 					pnfs_return_layout(inode, &args->rl.cbl_seg);
-					iput(inode);
+					/* keep inode for later */
 				}
 			} while(found);
 
 			if (args->rl.cbl_recall_type != RECALL_ALL)
 				break;
 		}
+
+		/* send final layoutreturn */
+		BUG_ON(inode == NULL);	/* should have returned NFS4ERR_NOMATCHING_LAYOUT */
+		lr_arg.reclaim = 0;
+		lr_arg.layout_type = NFS_SERVER(inode)->pnfs_curr_ld->id;
+		lr_arg.return_type = args->rl.cbl_recall_type;
+		lr_arg.lseg = args->rl.cbl_seg;
+		lr_arg.inode = inode;
+
+		status = pnfs_return_layout_rpc(server, &lr_arg);
+		iput(inode);
+		if (status)
+			printk("%s: ignoring pnfs_return_layout_rpc status=%d\n",
+			       __FUNCTION__, status);
 	}
 	up_read(&clp->cl_sem);
 
-- 
1.5.2.5



More information about the pNFS mailing list