|
@@ -86,6 +86,7 @@
|
|
| ATTR_MTIME_SET)
|
|
| ATTR_MTIME_SET)
|
|
|
|
|
|
struct nfs4_opendata;
|
|
struct nfs4_opendata;
|
|
|
|
+static void nfs4_layoutget_release(void *calldata);
|
|
static int _nfs4_recover_proc_open(struct nfs4_opendata *data);
|
|
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 int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *);
|
|
static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr);
|
|
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 */
|
|
#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)
|
|
static int nfs4_sequence_process(struct rpc_task *task, struct nfs4_sequence_res *res)
|
|
{
|
|
{
|
|
return nfs40_sequence_done(task, res);
|
|
return nfs40_sequence_done(task, res);
|
|
@@ -1244,6 +1249,8 @@ static void nfs4_opendata_free(struct kref *kref)
|
|
struct nfs4_opendata, kref);
|
|
struct nfs4_opendata, kref);
|
|
struct super_block *sb = p->dentry->d_sb;
|
|
struct super_block *sb = p->dentry->d_sb;
|
|
|
|
|
|
|
|
+ if (p->lgp)
|
|
|
|
+ nfs4_layoutget_release(p->lgp);
|
|
nfs_free_seqid(p->o_arg.seqid);
|
|
nfs_free_seqid(p->o_arg.seqid);
|
|
nfs4_sequence_free_slot(&p->o_res.seq_res);
|
|
nfs4_sequence_free_slot(&p->o_res.seq_res);
|
|
if (p->state != NULL)
|
|
if (p->state != NULL)
|
|
@@ -2334,8 +2341,10 @@ static int nfs4_run_open_task(struct nfs4_opendata *data,
|
|
if (!ctx) {
|
|
if (!ctx) {
|
|
nfs4_init_sequence(&o_arg->seq_args, &o_res->seq_res, 1, 1);
|
|
nfs4_init_sequence(&o_arg->seq_args, &o_res->seq_res, 1, 1);
|
|
data->is_recover = true;
|
|
data->is_recover = true;
|
|
- } else
|
|
|
|
|
|
+ } else {
|
|
nfs4_init_sequence(&o_arg->seq_args, &o_res->seq_res, 1, 0);
|
|
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);
|
|
task = rpc_run_task(&task_setup_data);
|
|
if (IS_ERR(task))
|
|
if (IS_ERR(task))
|
|
return PTR_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);
|
|
nfs_inode_attach_open_context(ctx);
|
|
if (read_seqcount_retry(&sp->so_reclaim_seqcount, seq))
|
|
if (read_seqcount_retry(&sp->so_reclaim_seqcount, seq))
|
|
nfs4_schedule_stateid_recovery(server, state);
|
|
nfs4_schedule_stateid_recovery(server, state);
|
|
|
|
+ else
|
|
|
|
+ pnfs_parse_lgopen(state->inode, opendata->lgp, ctx);
|
|
}
|
|
}
|
|
|
|
+
|
|
out:
|
|
out:
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
@@ -8722,13 +8734,14 @@ static void nfs4_layoutget_release(void *calldata)
|
|
{
|
|
{
|
|
struct nfs4_layoutget *lgp = calldata;
|
|
struct nfs4_layoutget *lgp = calldata;
|
|
struct inode *inode = lgp->args.inode;
|
|
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__);
|
|
dprintk("--> %s\n", __func__);
|
|
nfs4_sequence_free_slot(&lgp->res.seq_res);
|
|
nfs4_sequence_free_slot(&lgp->res.seq_res);
|
|
nfs4_free_pages(lgp->args.layout.pages, max_pages);
|
|
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);
|
|
put_nfs_open_context(lgp->args.ctx);
|
|
kfree(calldata);
|
|
kfree(calldata);
|
|
dprintk("<-- %s\n", __func__);
|
|
dprintk("<-- %s\n", __func__);
|