Merge branch 'open_state'

This commit is contained in:
Trond Myklebust
2017-08-15 11:54:13 -04:00
291 changed files with 4794 additions and 1387 deletions

View File

@@ -121,6 +121,7 @@ config PNFS_FILE_LAYOUT
config PNFS_BLOCK
tristate
depends on NFS_V4_1 && BLK_DEV_DM
depends on 64BIT || LBDAF
default NFS_V4
config PNFS_FLEXFILE_LAYOUT

View File

@@ -32,6 +32,7 @@ void nfs4_ff_layout_free_deviceid(struct nfs4_ff_layout_ds *mirror_ds)
{
nfs4_print_deviceid(&mirror_ds->id_node.deviceid);
nfs4_pnfs_ds_put(mirror_ds->ds);
kfree(mirror_ds->ds_versions);
kfree_rcu(mirror_ds, id_node.rcu);
}

View File

@@ -1659,12 +1659,52 @@ update:
return state;
}
static struct inode *
nfs4_opendata_get_inode(struct nfs4_opendata *data)
{
struct inode *inode;
switch (data->o_arg.claim) {
case NFS4_OPEN_CLAIM_NULL:
case NFS4_OPEN_CLAIM_DELEGATE_CUR:
case NFS4_OPEN_CLAIM_DELEGATE_PREV:
if (!(data->f_attr.valid & NFS_ATTR_FATTR))
return ERR_PTR(-EAGAIN);
inode = nfs_fhget(data->dir->d_sb, &data->o_res.fh,
&data->f_attr, data->f_label);
break;
default:
inode = d_inode(data->dentry);
ihold(inode);
nfs_refresh_inode(inode, &data->f_attr);
}
return inode;
}
static struct nfs4_state *
nfs4_opendata_find_nfs4_state(struct nfs4_opendata *data)
{
struct nfs4_state *state;
struct inode *inode;
inode = nfs4_opendata_get_inode(data);
if (IS_ERR(inode))
return ERR_CAST(inode);
if (data->state != NULL && data->state->inode == inode) {
state = data->state;
atomic_inc(&state->count);
} else
state = nfs4_get_open_state(inode, data->owner);
iput(inode);
if (state == NULL)
state = ERR_PTR(-ENOMEM);
return state;
}
static struct nfs4_state *
_nfs4_opendata_to_nfs4_state(struct nfs4_opendata *data)
{
struct inode *inode;
struct nfs4_state *state = NULL;
int ret;
struct nfs4_state *state;
if (!data->rpc_done) {
state = nfs4_try_open_cached(data);
@@ -1672,29 +1712,17 @@ _nfs4_opendata_to_nfs4_state(struct nfs4_opendata *data)
goto out;
}
ret = -EAGAIN;
if (!(data->f_attr.valid & NFS_ATTR_FATTR))
goto err;
inode = nfs_fhget(data->dir->d_sb, &data->o_res.fh, &data->f_attr, data->f_label);
ret = PTR_ERR(inode);
if (IS_ERR(inode))
goto err;
ret = -ENOMEM;
state = nfs4_get_open_state(inode, data->owner);
if (state == NULL)
goto err_put_inode;
state = nfs4_opendata_find_nfs4_state(data);
if (IS_ERR(state))
goto out;
if (data->o_res.delegation_type != 0)
nfs4_opendata_check_deleg(data, state);
update_open_stateid(state, &data->o_res.stateid, NULL,
data->o_arg.fmode);
iput(inode);
out:
nfs_release_seqid(data->o_arg.seqid);
return state;
err_put_inode:
iput(inode);
err:
return ERR_PTR(ret);
}
static struct nfs4_state *
@@ -2071,7 +2099,6 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata)
data->o_arg.open_bitmap = &nfs4_open_noattr_bitmap[0];
case NFS4_OPEN_CLAIM_FH:
task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_NOATTR];
nfs_copy_fh(&data->o_res.fh, data->o_arg.fh);
}
data->timestamp = jiffies;
if (nfs4_setup_sequence(data->o_arg.server->nfs_client,
@@ -2553,9 +2580,8 @@ static int nfs41_check_open_stateid(struct nfs4_state *state)
clear_bit(NFS_O_RDWR_STATE, &state->flags);
clear_bit(NFS_OPEN_STATE, &state->flags);
stateid->type = NFS4_INVALID_STATEID_TYPE;
}
if (status != NFS_OK)
return status;
}
if (nfs_open_stateid_recover_openmode(state))
return -NFS4ERR_OPENMODE;
return NFS_OK;