summaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4proc.c
diff options
context:
space:
mode:
authorFred Isaman <fred.isaman@gmail.com>2016-10-06 18:11:21 +0200
committerTrond Myklebust <trond.myklebust@hammerspace.com>2018-05-31 21:03:11 +0200
commit2409a976a2990ee1712c0945a75d75eeb3c60c08 (patch)
tree390eeba3931c247b5716a4ab4fafd52ab77bfc3a /fs/nfs/nfs4proc.c
parentpnfs: Change pnfs_alloc_init_layoutget_args call signature (diff)
downloadlinux-2409a976a2990ee1712c0945a75d75eeb3c60c08.tar.xz
linux-2409a976a2990ee1712c0945a75d75eeb3c60c08.zip
pnfs: Add LAYOUTGET to OPEN of a new file
This triggers when have no pre-existing inode to attach to. The preexisting case is saved for later. Signed-off-by: Fred Isaman <fred.isaman@gmail.com> Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r--fs/nfs/nfs4proc.c21
1 files changed, 17 insertions, 4 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index c7f982cdcbdd..062a9c753b7e 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -86,6 +86,7 @@
| ATTR_MTIME_SET)
struct nfs4_opendata;
+static void nfs4_layoutget_release(void *calldata);
static int _nfs4_recover_proc_open(struct nfs4_opendata *data);
static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *);
static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr);
@@ -877,6 +878,10 @@ nfs4_sequence_process_interrupted(struct nfs_client *client,
#else /* !CONFIG_NFS_V4_1 */
+static void nfs4_layoutget_release(void *calldata)
+{
+}
+
static int nfs4_sequence_process(struct rpc_task *task, struct nfs4_sequence_res *res)
{
return nfs40_sequence_done(task, res);
@@ -1244,6 +1249,8 @@ static void nfs4_opendata_free(struct kref *kref)
struct nfs4_opendata, kref);
struct super_block *sb = p->dentry->d_sb;
+ if (p->lgp)
+ nfs4_layoutget_release(p->lgp);
nfs_free_seqid(p->o_arg.seqid);
nfs4_sequence_free_slot(&p->o_res.seq_res);
if (p->state != NULL)
@@ -2334,8 +2341,10 @@ static int nfs4_run_open_task(struct nfs4_opendata *data,
if (!ctx) {
nfs4_init_sequence(&o_arg->seq_args, &o_res->seq_res, 1, 1);
data->is_recover = true;
- } else
+ } else {
nfs4_init_sequence(&o_arg->seq_args, &o_res->seq_res, 1, 0);
+ pnfs_lgopen_prepare(data, ctx);
+ }
task = rpc_run_task(&task_setup_data);
if (IS_ERR(task))
return PTR_ERR(task);
@@ -2815,7 +2824,10 @@ static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata,
nfs_inode_attach_open_context(ctx);
if (read_seqcount_retry(&sp->so_reclaim_seqcount, seq))
nfs4_schedule_stateid_recovery(server, state);
+ else
+ pnfs_parse_lgopen(state->inode, opendata->lgp, ctx);
}
+
out:
return ret;
}
@@ -8722,13 +8734,14 @@ static void nfs4_layoutget_release(void *calldata)
{
struct nfs4_layoutget *lgp = calldata;
struct inode *inode = lgp->args.inode;
- struct nfs_server *server = NFS_SERVER(inode);
- size_t max_pages = max_response_pages(server);
+ size_t max_pages = lgp->args.layout.pglen / PAGE_SIZE;
dprintk("--> %s\n", __func__);
nfs4_sequence_free_slot(&lgp->res.seq_res);
nfs4_free_pages(lgp->args.layout.pages, max_pages);
- pnfs_put_layout_hdr(NFS_I(inode)->layout);
+ if (inode)
+ pnfs_put_layout_hdr(NFS_I(inode)->layout);
+ put_rpccred(lgp->cred);
put_nfs_open_context(lgp->args.ctx);
kfree(calldata);
dprintk("<-- %s\n", __func__);