[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