Merge tag 'nfs-for-5.4-1' of git://git.linux-nfs.org/projects/anna/linux-nfs
Pull NFS client updates from Anna Schumaker: "Stable bugfixes: - Dequeue the request from the receive queue while we're re-encoding # v4.20+ - Fix buffer handling of GSS MIC without slack # 5.1 Features: - Increase xprtrdma maximum transport header and slot table sizes - Add support for nfs4_call_sync() calls using a custom rpc_task_struct - Optimize the default readahead size - Enable pNFS filelayout LAYOUTGET on OPEN Other bugfixes and cleanups: - Fix possible null-pointer dereferences and memory leaks - Various NFS over RDMA cleanups - Various NFS over RDMA comment updates - Don't receive TCP data into a reset request buffer - Don't try to parse incomplete RPC messages - Fix congestion window race with disconnect - Clean up pNFS return-on-close error handling - Fixes for NFS4ERR_OLD_STATEID handling" * tag 'nfs-for-5.4-1' of git://git.linux-nfs.org/projects/anna/linux-nfs: (53 commits) pNFS/filelayout: enable LAYOUTGET on OPEN NFS: Optimise the default readahead size NFSv4: Handle NFS4ERR_OLD_STATEID in LOCKU NFSv4: Handle NFS4ERR_OLD_STATEID in CLOSE/OPEN_DOWNGRADE NFSv4: Fix OPEN_DOWNGRADE error handling pNFS: Handle NFS4ERR_OLD_STATEID on layoutreturn by bumping the state seqid NFSv4: Add a helper to increment stateid seqids NFSv4: Handle RPC level errors in LAYOUTRETURN NFSv4: Handle NFS4ERR_DELAY correctly in return-on-close NFSv4: Clean up pNFS return-on-close error handling pNFS: Ensure we do clear the return-on-close layout stateid on fatal errors NFS: remove unused check for negative dentry NFSv3: use nfs_add_or_obtain() to create and reference inodes NFS: Refactor nfs_instantiate() for dentry referencing callers SUNRPC: Fix congestion window race with disconnect SUNRPC: Don't try to parse incomplete RPC messages SUNRPC: Rename xdr_buf_read_netobj to xdr_buf_read_mic SUNRPC: Fix buffer handling of GSS MIC without slack SUNRPC: RPC level errors should always set task->tk_rpc_status SUNRPC: Don't receive TCP data into a request buffer that has been reset ...
This commit is contained in:
41
fs/nfs/dir.c
41
fs/nfs/dir.c
@@ -1669,10 +1669,8 @@ static int nfs4_lookup_revalidate(struct dentry *dentry, unsigned int flags)
|
||||
|
||||
#endif /* CONFIG_NFSV4 */
|
||||
|
||||
/*
|
||||
* Code common to create, mkdir, and mknod.
|
||||
*/
|
||||
int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fhandle,
|
||||
struct dentry *
|
||||
nfs_add_or_obtain(struct dentry *dentry, struct nfs_fh *fhandle,
|
||||
struct nfs_fattr *fattr,
|
||||
struct nfs4_label *label)
|
||||
{
|
||||
@@ -1680,13 +1678,10 @@ int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fhandle,
|
||||
struct inode *dir = d_inode(parent);
|
||||
struct inode *inode;
|
||||
struct dentry *d;
|
||||
int error = -EACCES;
|
||||
int error;
|
||||
|
||||
d_drop(dentry);
|
||||
|
||||
/* We may have been initialized further down */
|
||||
if (d_really_is_positive(dentry))
|
||||
goto out;
|
||||
if (fhandle->size == 0) {
|
||||
error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr, NULL);
|
||||
if (error)
|
||||
@@ -1702,18 +1697,32 @@ int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fhandle,
|
||||
}
|
||||
inode = nfs_fhget(dentry->d_sb, fhandle, fattr, label);
|
||||
d = d_splice_alias(inode, dentry);
|
||||
if (IS_ERR(d)) {
|
||||
error = PTR_ERR(d);
|
||||
goto out_error;
|
||||
}
|
||||
dput(d);
|
||||
out:
|
||||
dput(parent);
|
||||
return 0;
|
||||
return d;
|
||||
out_error:
|
||||
nfs_mark_for_revalidate(dir);
|
||||
dput(parent);
|
||||
return error;
|
||||
d = ERR_PTR(error);
|
||||
goto out;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_add_or_obtain);
|
||||
|
||||
/*
|
||||
* Code common to create, mkdir, and mknod.
|
||||
*/
|
||||
int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fhandle,
|
||||
struct nfs_fattr *fattr,
|
||||
struct nfs4_label *label)
|
||||
{
|
||||
struct dentry *d;
|
||||
|
||||
d = nfs_add_or_obtain(dentry, fhandle, fattr, label);
|
||||
if (IS_ERR(d))
|
||||
return PTR_ERR(d);
|
||||
|
||||
/* Callers don't care */
|
||||
dput(d);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_instantiate);
|
||||
|
||||
|
@@ -1164,6 +1164,7 @@ static struct pnfs_layoutdriver_type filelayout_type = {
|
||||
.id = LAYOUT_NFSV4_1_FILES,
|
||||
.name = "LAYOUT_NFSV4_1_FILES",
|
||||
.owner = THIS_MODULE,
|
||||
.flags = PNFS_LAYOUTGET_ON_OPEN,
|
||||
.max_layoutget_response = 4096, /* 1 page or so... */
|
||||
.alloc_layout_hdr = filelayout_alloc_layout_hdr,
|
||||
.free_layout_hdr = filelayout_free_layout_hdr,
|
||||
|
@@ -16,14 +16,6 @@ extern const struct export_operations nfs_export_ops;
|
||||
|
||||
struct nfs_string;
|
||||
|
||||
/* Maximum number of readahead requests
|
||||
* FIXME: this should really be a sysctl so that users may tune it to suit
|
||||
* their needs. People that do NFS over a slow network, might for
|
||||
* instance want to reduce it to something closer to 1 for improved
|
||||
* interactive response.
|
||||
*/
|
||||
#define NFS_MAX_READAHEAD (RPC_DEF_SLOT_TABLE - 1)
|
||||
|
||||
static inline void nfs_attr_check_mountpoint(struct super_block *parent, struct nfs_fattr *fattr)
|
||||
{
|
||||
if (!nfs_fsid_equal(&NFS_SB(parent)->fsid, &fattr->fsid))
|
||||
|
@@ -279,15 +279,17 @@ static struct nfs3_createdata *nfs3_alloc_createdata(void)
|
||||
return data;
|
||||
}
|
||||
|
||||
static int nfs3_do_create(struct inode *dir, struct dentry *dentry, struct nfs3_createdata *data)
|
||||
static struct dentry *
|
||||
nfs3_do_create(struct inode *dir, struct dentry *dentry, struct nfs3_createdata *data)
|
||||
{
|
||||
int status;
|
||||
|
||||
status = rpc_call_sync(NFS_CLIENT(dir), &data->msg, 0);
|
||||
nfs_post_op_update_inode(dir, data->res.dir_attr);
|
||||
if (status == 0)
|
||||
status = nfs_instantiate(dentry, data->res.fh, data->res.fattr, NULL);
|
||||
return status;
|
||||
if (status != 0)
|
||||
return ERR_PTR(status);
|
||||
|
||||
return nfs_add_or_obtain(dentry, data->res.fh, data->res.fattr, NULL);
|
||||
}
|
||||
|
||||
static void nfs3_free_createdata(struct nfs3_createdata *data)
|
||||
@@ -304,6 +306,7 @@ nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
|
||||
{
|
||||
struct posix_acl *default_acl, *acl;
|
||||
struct nfs3_createdata *data;
|
||||
struct dentry *d_alias;
|
||||
int status = -ENOMEM;
|
||||
|
||||
dprintk("NFS call create %pd\n", dentry);
|
||||
@@ -330,7 +333,8 @@ nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
|
||||
goto out;
|
||||
|
||||
for (;;) {
|
||||
status = nfs3_do_create(dir, dentry, data);
|
||||
d_alias = nfs3_do_create(dir, dentry, data);
|
||||
status = PTR_ERR_OR_ZERO(d_alias);
|
||||
|
||||
if (status != -ENOTSUPP)
|
||||
break;
|
||||
@@ -355,6 +359,9 @@ nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
|
||||
if (status != 0)
|
||||
goto out_release_acls;
|
||||
|
||||
if (d_alias)
|
||||
dentry = d_alias;
|
||||
|
||||
/* When we created the file with exclusive semantics, make
|
||||
* sure we set the attributes afterwards. */
|
||||
if (data->arg.create.createmode == NFS3_CREATE_EXCLUSIVE) {
|
||||
@@ -372,11 +379,13 @@ nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
|
||||
nfs_post_op_update_inode(d_inode(dentry), data->res.fattr);
|
||||
dprintk("NFS reply setattr (post-create): %d\n", status);
|
||||
if (status != 0)
|
||||
goto out_release_acls;
|
||||
goto out_dput;
|
||||
}
|
||||
|
||||
status = nfs3_proc_setacls(d_inode(dentry), acl, default_acl);
|
||||
|
||||
out_dput:
|
||||
dput(d_alias);
|
||||
out_release_acls:
|
||||
posix_acl_release(acl);
|
||||
posix_acl_release(default_acl);
|
||||
@@ -504,6 +513,7 @@ nfs3_proc_symlink(struct inode *dir, struct dentry *dentry, struct page *page,
|
||||
unsigned int len, struct iattr *sattr)
|
||||
{
|
||||
struct nfs3_createdata *data;
|
||||
struct dentry *d_alias;
|
||||
int status = -ENOMEM;
|
||||
|
||||
if (len > NFS3_MAXPATHLEN)
|
||||
@@ -522,7 +532,11 @@ nfs3_proc_symlink(struct inode *dir, struct dentry *dentry, struct page *page,
|
||||
data->arg.symlink.pathlen = len;
|
||||
data->arg.symlink.sattr = sattr;
|
||||
|
||||
status = nfs3_do_create(dir, dentry, data);
|
||||
d_alias = nfs3_do_create(dir, dentry, data);
|
||||
status = PTR_ERR_OR_ZERO(d_alias);
|
||||
|
||||
if (status == 0)
|
||||
dput(d_alias);
|
||||
|
||||
nfs3_free_createdata(data);
|
||||
out:
|
||||
@@ -535,6 +549,7 @@ nfs3_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr)
|
||||
{
|
||||
struct posix_acl *default_acl, *acl;
|
||||
struct nfs3_createdata *data;
|
||||
struct dentry *d_alias;
|
||||
int status = -ENOMEM;
|
||||
|
||||
dprintk("NFS call mkdir %pd\n", dentry);
|
||||
@@ -553,12 +568,18 @@ nfs3_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr)
|
||||
data->arg.mkdir.len = dentry->d_name.len;
|
||||
data->arg.mkdir.sattr = sattr;
|
||||
|
||||
status = nfs3_do_create(dir, dentry, data);
|
||||
d_alias = nfs3_do_create(dir, dentry, data);
|
||||
status = PTR_ERR_OR_ZERO(d_alias);
|
||||
|
||||
if (status != 0)
|
||||
goto out_release_acls;
|
||||
|
||||
if (d_alias)
|
||||
dentry = d_alias;
|
||||
|
||||
status = nfs3_proc_setacls(d_inode(dentry), acl, default_acl);
|
||||
|
||||
dput(d_alias);
|
||||
out_release_acls:
|
||||
posix_acl_release(acl);
|
||||
posix_acl_release(default_acl);
|
||||
@@ -660,6 +681,7 @@ nfs3_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
|
||||
{
|
||||
struct posix_acl *default_acl, *acl;
|
||||
struct nfs3_createdata *data;
|
||||
struct dentry *d_alias;
|
||||
int status = -ENOMEM;
|
||||
|
||||
dprintk("NFS call mknod %pd %u:%u\n", dentry,
|
||||
@@ -698,12 +720,17 @@ nfs3_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
|
||||
goto out;
|
||||
}
|
||||
|
||||
status = nfs3_do_create(dir, dentry, data);
|
||||
d_alias = nfs3_do_create(dir, dentry, data);
|
||||
status = PTR_ERR_OR_ZERO(d_alias);
|
||||
if (status != 0)
|
||||
goto out_release_acls;
|
||||
|
||||
if (d_alias)
|
||||
dentry = d_alias;
|
||||
|
||||
status = nfs3_proc_setacls(d_inode(dentry), acl, default_acl);
|
||||
|
||||
dput(d_alias);
|
||||
out_release_acls:
|
||||
posix_acl_release(acl);
|
||||
posix_acl_release(default_acl);
|
||||
|
@@ -491,8 +491,6 @@ extern int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl);
|
||||
extern int nfs4_select_rw_stateid(struct nfs4_state *, fmode_t,
|
||||
const struct nfs_lock_context *, nfs4_stateid *,
|
||||
const struct cred **);
|
||||
extern bool nfs4_refresh_open_stateid(nfs4_stateid *dst,
|
||||
struct nfs4_state *state);
|
||||
extern bool nfs4_copy_open_stateid(nfs4_stateid *dst,
|
||||
struct nfs4_state *state);
|
||||
|
||||
@@ -574,6 +572,15 @@ static inline bool nfs4_stateid_is_newer(const nfs4_stateid *s1, const nfs4_stat
|
||||
return (s32)(be32_to_cpu(s1->seqid) - be32_to_cpu(s2->seqid)) > 0;
|
||||
}
|
||||
|
||||
static inline void nfs4_stateid_seqid_inc(nfs4_stateid *s1)
|
||||
{
|
||||
u32 seqid = be32_to_cpu(s1->seqid);
|
||||
|
||||
if (++seqid == 0)
|
||||
++seqid;
|
||||
s1->seqid = cpu_to_be32(seqid);
|
||||
}
|
||||
|
||||
static inline bool nfs4_valid_open_stateid(const struct nfs4_state *state)
|
||||
{
|
||||
return test_bit(NFS_STATE_RECOVERY_FAILED, &state->flags) == 0;
|
||||
|
@@ -1073,14 +1073,26 @@ static const struct rpc_call_ops nfs40_call_sync_ops = {
|
||||
.rpc_call_done = nfs40_call_sync_done,
|
||||
};
|
||||
|
||||
static int nfs4_call_sync_custom(struct rpc_task_setup *task_setup)
|
||||
{
|
||||
int ret;
|
||||
struct rpc_task *task;
|
||||
|
||||
task = rpc_run_task(task_setup);
|
||||
if (IS_ERR(task))
|
||||
return PTR_ERR(task);
|
||||
|
||||
ret = task->tk_status;
|
||||
rpc_put_task(task);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int nfs4_call_sync_sequence(struct rpc_clnt *clnt,
|
||||
struct nfs_server *server,
|
||||
struct rpc_message *msg,
|
||||
struct nfs4_sequence_args *args,
|
||||
struct nfs4_sequence_res *res)
|
||||
{
|
||||
int ret;
|
||||
struct rpc_task *task;
|
||||
struct nfs_client *clp = server->nfs_client;
|
||||
struct nfs4_call_sync_data data = {
|
||||
.seq_server = server,
|
||||
@@ -1094,14 +1106,7 @@ static int nfs4_call_sync_sequence(struct rpc_clnt *clnt,
|
||||
.callback_data = &data
|
||||
};
|
||||
|
||||
task = rpc_run_task(&task_setup);
|
||||
if (IS_ERR(task))
|
||||
ret = PTR_ERR(task);
|
||||
else {
|
||||
ret = task->tk_status;
|
||||
rpc_put_task(task);
|
||||
}
|
||||
return ret;
|
||||
return nfs4_call_sync_custom(&task_setup);
|
||||
}
|
||||
|
||||
int nfs4_call_sync(struct rpc_clnt *clnt,
|
||||
@@ -3308,6 +3313,75 @@ nfs4_wait_on_layoutreturn(struct inode *inode, struct rpc_task *task)
|
||||
return pnfs_wait_on_layoutreturn(inode, task);
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the seqid of an open stateid
|
||||
*/
|
||||
static void nfs4_sync_open_stateid(nfs4_stateid *dst,
|
||||
struct nfs4_state *state)
|
||||
{
|
||||
__be32 seqid_open;
|
||||
u32 dst_seqid;
|
||||
int seq;
|
||||
|
||||
for (;;) {
|
||||
if (!nfs4_valid_open_stateid(state))
|
||||
break;
|
||||
seq = read_seqbegin(&state->seqlock);
|
||||
if (!nfs4_state_match_open_stateid_other(state, dst)) {
|
||||
nfs4_stateid_copy(dst, &state->open_stateid);
|
||||
if (read_seqretry(&state->seqlock, seq))
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
seqid_open = state->open_stateid.seqid;
|
||||
if (read_seqretry(&state->seqlock, seq))
|
||||
continue;
|
||||
|
||||
dst_seqid = be32_to_cpu(dst->seqid);
|
||||
if ((s32)(dst_seqid - be32_to_cpu(seqid_open)) < 0)
|
||||
dst->seqid = seqid_open;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the seqid of an open stateid after receiving
|
||||
* NFS4ERR_OLD_STATEID
|
||||
*/
|
||||
static bool nfs4_refresh_open_old_stateid(nfs4_stateid *dst,
|
||||
struct nfs4_state *state)
|
||||
{
|
||||
__be32 seqid_open;
|
||||
u32 dst_seqid;
|
||||
bool ret;
|
||||
int seq;
|
||||
|
||||
for (;;) {
|
||||
ret = false;
|
||||
if (!nfs4_valid_open_stateid(state))
|
||||
break;
|
||||
seq = read_seqbegin(&state->seqlock);
|
||||
if (!nfs4_state_match_open_stateid_other(state, dst)) {
|
||||
if (read_seqretry(&state->seqlock, seq))
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
seqid_open = state->open_stateid.seqid;
|
||||
if (read_seqretry(&state->seqlock, seq))
|
||||
continue;
|
||||
|
||||
dst_seqid = be32_to_cpu(dst->seqid);
|
||||
if ((s32)(dst_seqid - be32_to_cpu(seqid_open)) >= 0)
|
||||
dst->seqid = cpu_to_be32(dst_seqid + 1);
|
||||
else
|
||||
dst->seqid = seqid_open;
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct nfs4_closedata {
|
||||
struct inode *inode;
|
||||
struct nfs4_state *state;
|
||||
@@ -3358,32 +3432,11 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
|
||||
trace_nfs4_close(state, &calldata->arg, &calldata->res, task->tk_status);
|
||||
|
||||
/* Handle Layoutreturn errors */
|
||||
if (calldata->arg.lr_args && task->tk_status != 0) {
|
||||
switch (calldata->res.lr_ret) {
|
||||
default:
|
||||
calldata->res.lr_ret = -NFS4ERR_NOMATCHING_LAYOUT;
|
||||
break;
|
||||
case 0:
|
||||
calldata->arg.lr_args = NULL;
|
||||
calldata->res.lr_res = NULL;
|
||||
break;
|
||||
case -NFS4ERR_OLD_STATEID:
|
||||
if (nfs4_layoutreturn_refresh_stateid(&calldata->arg.lr_args->stateid,
|
||||
&calldata->arg.lr_args->range,
|
||||
calldata->inode))
|
||||
goto lr_restart;
|
||||
/* Fallthrough */
|
||||
case -NFS4ERR_ADMIN_REVOKED:
|
||||
case -NFS4ERR_DELEG_REVOKED:
|
||||
case -NFS4ERR_EXPIRED:
|
||||
case -NFS4ERR_BAD_STATEID:
|
||||
case -NFS4ERR_UNKNOWN_LAYOUTTYPE:
|
||||
case -NFS4ERR_WRONG_CRED:
|
||||
calldata->arg.lr_args = NULL;
|
||||
calldata->res.lr_res = NULL;
|
||||
goto lr_restart;
|
||||
}
|
||||
}
|
||||
if (pnfs_roc_done(task, calldata->inode,
|
||||
&calldata->arg.lr_args,
|
||||
&calldata->res.lr_res,
|
||||
&calldata->res.lr_ret) == -EAGAIN)
|
||||
goto out_restart;
|
||||
|
||||
/* hmm. we are done with the inode, and in the process of freeing
|
||||
* the state_owner. we keep this around to process errors
|
||||
@@ -3403,7 +3456,7 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
|
||||
break;
|
||||
case -NFS4ERR_OLD_STATEID:
|
||||
/* Did we race with OPEN? */
|
||||
if (nfs4_refresh_open_stateid(&calldata->arg.stateid,
|
||||
if (nfs4_refresh_open_old_stateid(&calldata->arg.stateid,
|
||||
state))
|
||||
goto out_restart;
|
||||
goto out_release;
|
||||
@@ -3415,7 +3468,9 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
|
||||
task->tk_msg.rpc_cred);
|
||||
/* Fallthrough */
|
||||
case -NFS4ERR_BAD_STATEID:
|
||||
break;
|
||||
if (calldata->arg.fmode == 0)
|
||||
break;
|
||||
/* Fallthrough */
|
||||
default:
|
||||
task->tk_status = nfs4_async_handle_exception(task,
|
||||
server, task->tk_status, &exception);
|
||||
@@ -3430,8 +3485,6 @@ out_release:
|
||||
nfs_refresh_inode(calldata->inode, &calldata->fattr);
|
||||
dprintk("%s: done, ret = %d!\n", __func__, task->tk_status);
|
||||
return;
|
||||
lr_restart:
|
||||
calldata->res.lr_ret = 0;
|
||||
out_restart:
|
||||
task->tk_status = 0;
|
||||
rpc_restart_call_prepare(task);
|
||||
@@ -3472,8 +3525,8 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
|
||||
} else if (is_rdwr)
|
||||
calldata->arg.fmode |= FMODE_READ|FMODE_WRITE;
|
||||
|
||||
if (!nfs4_valid_open_stateid(state) ||
|
||||
!nfs4_refresh_open_stateid(&calldata->arg.stateid, state))
|
||||
nfs4_sync_open_stateid(&calldata->arg.stateid, state);
|
||||
if (!nfs4_valid_open_stateid(state))
|
||||
call_close = 0;
|
||||
spin_unlock(&state->owner->so_lock);
|
||||
|
||||
@@ -6018,7 +6071,6 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program,
|
||||
.rpc_resp = res,
|
||||
.rpc_cred = cred,
|
||||
};
|
||||
struct rpc_task *task;
|
||||
struct rpc_task_setup task_setup_data = {
|
||||
.rpc_client = clp->cl_rpcclient,
|
||||
.rpc_message = &msg,
|
||||
@@ -6051,17 +6103,12 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program,
|
||||
dprintk("NFS call setclientid auth=%s, '%s'\n",
|
||||
clp->cl_rpcclient->cl_auth->au_ops->au_name,
|
||||
clp->cl_owner_id);
|
||||
task = rpc_run_task(&task_setup_data);
|
||||
if (IS_ERR(task)) {
|
||||
status = PTR_ERR(task);
|
||||
goto out;
|
||||
}
|
||||
status = task->tk_status;
|
||||
|
||||
status = nfs4_call_sync_custom(&task_setup_data);
|
||||
if (setclientid.sc_cred) {
|
||||
clp->cl_acceptor = rpcauth_stringify_acceptor(setclientid.sc_cred);
|
||||
put_rpccred(setclientid.sc_cred);
|
||||
}
|
||||
rpc_put_task(task);
|
||||
out:
|
||||
trace_nfs4_setclientid(clp, status);
|
||||
dprintk("NFS reply setclientid: %d\n", status);
|
||||
@@ -6129,32 +6176,11 @@ static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata)
|
||||
trace_nfs4_delegreturn_exit(&data->args, &data->res, task->tk_status);
|
||||
|
||||
/* Handle Layoutreturn errors */
|
||||
if (data->args.lr_args && task->tk_status != 0) {
|
||||
switch(data->res.lr_ret) {
|
||||
default:
|
||||
data->res.lr_ret = -NFS4ERR_NOMATCHING_LAYOUT;
|
||||
break;
|
||||
case 0:
|
||||
data->args.lr_args = NULL;
|
||||
data->res.lr_res = NULL;
|
||||
break;
|
||||
case -NFS4ERR_OLD_STATEID:
|
||||
if (nfs4_layoutreturn_refresh_stateid(&data->args.lr_args->stateid,
|
||||
&data->args.lr_args->range,
|
||||
data->inode))
|
||||
goto lr_restart;
|
||||
/* Fallthrough */
|
||||
case -NFS4ERR_ADMIN_REVOKED:
|
||||
case -NFS4ERR_DELEG_REVOKED:
|
||||
case -NFS4ERR_EXPIRED:
|
||||
case -NFS4ERR_BAD_STATEID:
|
||||
case -NFS4ERR_UNKNOWN_LAYOUTTYPE:
|
||||
case -NFS4ERR_WRONG_CRED:
|
||||
data->args.lr_args = NULL;
|
||||
data->res.lr_res = NULL;
|
||||
goto lr_restart;
|
||||
}
|
||||
}
|
||||
if (pnfs_roc_done(task, data->inode,
|
||||
&data->args.lr_args,
|
||||
&data->res.lr_res,
|
||||
&data->res.lr_ret) == -EAGAIN)
|
||||
goto out_restart;
|
||||
|
||||
switch (task->tk_status) {
|
||||
case 0:
|
||||
@@ -6192,8 +6218,6 @@ static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata)
|
||||
}
|
||||
data->rpc_status = task->tk_status;
|
||||
return;
|
||||
lr_restart:
|
||||
data->res.lr_ret = 0;
|
||||
out_restart:
|
||||
task->tk_status = 0;
|
||||
rpc_restart_call_prepare(task);
|
||||
@@ -6386,6 +6410,42 @@ static int nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock *
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the seqid of a lock stateid after receiving
|
||||
* NFS4ERR_OLD_STATEID
|
||||
*/
|
||||
static bool nfs4_refresh_lock_old_stateid(nfs4_stateid *dst,
|
||||
struct nfs4_lock_state *lsp)
|
||||
{
|
||||
struct nfs4_state *state = lsp->ls_state;
|
||||
bool ret = false;
|
||||
|
||||
spin_lock(&state->state_lock);
|
||||
if (!nfs4_stateid_match_other(dst, &lsp->ls_stateid))
|
||||
goto out;
|
||||
if (!nfs4_stateid_is_newer(&lsp->ls_stateid, dst))
|
||||
nfs4_stateid_seqid_inc(dst);
|
||||
else
|
||||
dst->seqid = lsp->ls_stateid.seqid;
|
||||
ret = true;
|
||||
out:
|
||||
spin_unlock(&state->state_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool nfs4_sync_lock_stateid(nfs4_stateid *dst,
|
||||
struct nfs4_lock_state *lsp)
|
||||
{
|
||||
struct nfs4_state *state = lsp->ls_state;
|
||||
bool ret;
|
||||
|
||||
spin_lock(&state->state_lock);
|
||||
ret = !nfs4_stateid_match_other(dst, &lsp->ls_stateid);
|
||||
nfs4_stateid_copy(dst, &lsp->ls_stateid);
|
||||
spin_unlock(&state->state_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct nfs4_unlockdata {
|
||||
struct nfs_locku_args arg;
|
||||
struct nfs_locku_res res;
|
||||
@@ -6403,7 +6463,8 @@ static struct nfs4_unlockdata *nfs4_alloc_unlockdata(struct file_lock *fl,
|
||||
struct nfs_seqid *seqid)
|
||||
{
|
||||
struct nfs4_unlockdata *p;
|
||||
struct inode *inode = lsp->ls_state->inode;
|
||||
struct nfs4_state *state = lsp->ls_state;
|
||||
struct inode *inode = state->inode;
|
||||
|
||||
p = kzalloc(sizeof(*p), GFP_NOFS);
|
||||
if (p == NULL)
|
||||
@@ -6419,6 +6480,9 @@ static struct nfs4_unlockdata *nfs4_alloc_unlockdata(struct file_lock *fl,
|
||||
locks_init_lock(&p->fl);
|
||||
locks_copy_lock(&p->fl, fl);
|
||||
p->server = NFS_SERVER(inode);
|
||||
spin_lock(&state->state_lock);
|
||||
nfs4_stateid_copy(&p->arg.stateid, &lsp->ls_stateid);
|
||||
spin_unlock(&state->state_lock);
|
||||
return p;
|
||||
}
|
||||
|
||||
@@ -6457,10 +6521,14 @@ static void nfs4_locku_done(struct rpc_task *task, void *data)
|
||||
task->tk_msg.rpc_cred);
|
||||
/* Fall through */
|
||||
case -NFS4ERR_BAD_STATEID:
|
||||
case -NFS4ERR_OLD_STATEID:
|
||||
case -NFS4ERR_STALE_STATEID:
|
||||
if (!nfs4_stateid_match(&calldata->arg.stateid,
|
||||
&calldata->lsp->ls_stateid))
|
||||
if (nfs4_sync_lock_stateid(&calldata->arg.stateid,
|
||||
calldata->lsp))
|
||||
rpc_restart_call_prepare(task);
|
||||
break;
|
||||
case -NFS4ERR_OLD_STATEID:
|
||||
if (nfs4_refresh_lock_old_stateid(&calldata->arg.stateid,
|
||||
calldata->lsp))
|
||||
rpc_restart_call_prepare(task);
|
||||
break;
|
||||
default:
|
||||
@@ -6483,7 +6551,6 @@ static void nfs4_locku_prepare(struct rpc_task *task, void *data)
|
||||
|
||||
if (nfs_wait_on_sequence(calldata->arg.seqid, task) != 0)
|
||||
goto out_wait;
|
||||
nfs4_stateid_copy(&calldata->arg.stateid, &calldata->lsp->ls_stateid);
|
||||
if (test_bit(NFS_LOCK_INITIALIZED, &calldata->lsp->ls_flags) == 0) {
|
||||
/* Note: exit _without_ running nfs4_locku_done */
|
||||
goto out_no_action;
|
||||
@@ -7645,6 +7712,8 @@ int nfs4_proc_fsid_present(struct inode *inode, const struct cred *cred)
|
||||
static int _nfs4_proc_secinfo(struct inode *dir, const struct qstr *name, struct nfs4_secinfo_flavors *flavors, bool use_integrity)
|
||||
{
|
||||
int status;
|
||||
struct rpc_clnt *clnt = NFS_SERVER(dir)->client;
|
||||
struct nfs_client *clp = NFS_SERVER(dir)->nfs_client;
|
||||
struct nfs4_secinfo_arg args = {
|
||||
.dir_fh = NFS_FH(dir),
|
||||
.name = name,
|
||||
@@ -7657,26 +7726,37 @@ static int _nfs4_proc_secinfo(struct inode *dir, const struct qstr *name, struct
|
||||
.rpc_argp = &args,
|
||||
.rpc_resp = &res,
|
||||
};
|
||||
struct rpc_clnt *clnt = NFS_SERVER(dir)->client;
|
||||
struct nfs4_call_sync_data data = {
|
||||
.seq_server = NFS_SERVER(dir),
|
||||
.seq_args = &args.seq_args,
|
||||
.seq_res = &res.seq_res,
|
||||
};
|
||||
struct rpc_task_setup task_setup = {
|
||||
.rpc_client = clnt,
|
||||
.rpc_message = &msg,
|
||||
.callback_ops = clp->cl_mvops->call_sync_ops,
|
||||
.callback_data = &data,
|
||||
.flags = RPC_TASK_NO_ROUND_ROBIN,
|
||||
};
|
||||
const struct cred *cred = NULL;
|
||||
|
||||
if (use_integrity) {
|
||||
clnt = NFS_SERVER(dir)->nfs_client->cl_rpcclient;
|
||||
cred = nfs4_get_clid_cred(NFS_SERVER(dir)->nfs_client);
|
||||
clnt = clp->cl_rpcclient;
|
||||
task_setup.rpc_client = clnt;
|
||||
|
||||
cred = nfs4_get_clid_cred(clp);
|
||||
msg.rpc_cred = cred;
|
||||
}
|
||||
|
||||
dprintk("NFS call secinfo %s\n", name->name);
|
||||
|
||||
nfs4_state_protect(NFS_SERVER(dir)->nfs_client,
|
||||
NFS_SP4_MACH_CRED_SECINFO, &clnt, &msg);
|
||||
nfs4_state_protect(clp, NFS_SP4_MACH_CRED_SECINFO, &clnt, &msg);
|
||||
nfs4_init_sequence(&args.seq_args, &res.seq_res, 0, 0);
|
||||
status = nfs4_call_sync_custom(&task_setup);
|
||||
|
||||
status = nfs4_call_sync(clnt, NFS_SERVER(dir), &msg, &args.seq_args,
|
||||
&res.seq_res, RPC_TASK_NO_ROUND_ROBIN);
|
||||
dprintk("NFS reply secinfo: %d\n", status);
|
||||
|
||||
put_cred(cred);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -8344,7 +8424,6 @@ static const struct rpc_call_ops nfs4_get_lease_time_ops = {
|
||||
|
||||
int nfs4_proc_get_lease_time(struct nfs_client *clp, struct nfs_fsinfo *fsinfo)
|
||||
{
|
||||
struct rpc_task *task;
|
||||
struct nfs4_get_lease_time_args args;
|
||||
struct nfs4_get_lease_time_res res = {
|
||||
.lr_fsinfo = fsinfo,
|
||||
@@ -8366,17 +8445,9 @@ int nfs4_proc_get_lease_time(struct nfs_client *clp, struct nfs_fsinfo *fsinfo)
|
||||
.callback_data = &data,
|
||||
.flags = RPC_TASK_TIMEOUT,
|
||||
};
|
||||
int status;
|
||||
|
||||
nfs4_init_sequence(&args.la_seq_args, &res.lr_seq_res, 0, 1);
|
||||
task = rpc_run_task(&task_setup);
|
||||
|
||||
if (IS_ERR(task))
|
||||
return PTR_ERR(task);
|
||||
|
||||
status = task->tk_status;
|
||||
rpc_put_task(task);
|
||||
return status;
|
||||
return nfs4_call_sync_custom(&task_setup);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NFS_V4_1
|
||||
@@ -8845,7 +8916,6 @@ static int nfs41_proc_reclaim_complete(struct nfs_client *clp,
|
||||
const struct cred *cred)
|
||||
{
|
||||
struct nfs4_reclaim_complete_data *calldata;
|
||||
struct rpc_task *task;
|
||||
struct rpc_message msg = {
|
||||
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RECLAIM_COMPLETE],
|
||||
.rpc_cred = cred,
|
||||
@@ -8854,7 +8924,7 @@ static int nfs41_proc_reclaim_complete(struct nfs_client *clp,
|
||||
.rpc_client = clp->cl_rpcclient,
|
||||
.rpc_message = &msg,
|
||||
.callback_ops = &nfs4_reclaim_complete_call_ops,
|
||||
.flags = RPC_TASK_ASYNC | RPC_TASK_NO_ROUND_ROBIN,
|
||||
.flags = RPC_TASK_NO_ROUND_ROBIN,
|
||||
};
|
||||
int status = -ENOMEM;
|
||||
|
||||
@@ -8869,15 +8939,7 @@ static int nfs41_proc_reclaim_complete(struct nfs_client *clp,
|
||||
msg.rpc_argp = &calldata->arg;
|
||||
msg.rpc_resp = &calldata->res;
|
||||
task_setup_data.callback_data = calldata;
|
||||
task = rpc_run_task(&task_setup_data);
|
||||
if (IS_ERR(task)) {
|
||||
status = PTR_ERR(task);
|
||||
goto out;
|
||||
}
|
||||
status = rpc_wait_for_completion_task(task);
|
||||
if (status == 0)
|
||||
status = task->tk_status;
|
||||
rpc_put_task(task);
|
||||
status = nfs4_call_sync_custom(&task_setup_data);
|
||||
out:
|
||||
dprintk("<-- %s status=%d\n", __func__, status);
|
||||
return status;
|
||||
@@ -9103,10 +9165,19 @@ static void nfs4_layoutreturn_done(struct rpc_task *task, void *calldata)
|
||||
if (!nfs41_sequence_process(task, &lrp->res.seq_res))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Was there an RPC level error? Assume the call succeeded,
|
||||
* and that we need to release the layout
|
||||
*/
|
||||
if (task->tk_rpc_status != 0 && RPC_WAS_SENT(task)) {
|
||||
lrp->res.lrs_present = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
server = NFS_SERVER(lrp->args.inode);
|
||||
switch (task->tk_status) {
|
||||
case -NFS4ERR_OLD_STATEID:
|
||||
if (nfs4_layoutreturn_refresh_stateid(&lrp->args.stateid,
|
||||
if (nfs4_layout_refresh_old_stateid(&lrp->args.stateid,
|
||||
&lrp->args.range,
|
||||
lrp->args.inode))
|
||||
goto out_restart;
|
||||
@@ -9362,18 +9433,32 @@ _nfs41_proc_secinfo_no_name(struct nfs_server *server, struct nfs_fh *fhandle,
|
||||
.rpc_resp = &res,
|
||||
};
|
||||
struct rpc_clnt *clnt = server->client;
|
||||
struct nfs4_call_sync_data data = {
|
||||
.seq_server = server,
|
||||
.seq_args = &args.seq_args,
|
||||
.seq_res = &res.seq_res,
|
||||
};
|
||||
struct rpc_task_setup task_setup = {
|
||||
.rpc_client = server->client,
|
||||
.rpc_message = &msg,
|
||||
.callback_ops = server->nfs_client->cl_mvops->call_sync_ops,
|
||||
.callback_data = &data,
|
||||
.flags = RPC_TASK_NO_ROUND_ROBIN,
|
||||
};
|
||||
const struct cred *cred = NULL;
|
||||
int status;
|
||||
|
||||
if (use_integrity) {
|
||||
clnt = server->nfs_client->cl_rpcclient;
|
||||
task_setup.rpc_client = clnt;
|
||||
|
||||
cred = nfs4_get_clid_cred(server->nfs_client);
|
||||
msg.rpc_cred = cred;
|
||||
}
|
||||
|
||||
dprintk("--> %s\n", __func__);
|
||||
status = nfs4_call_sync(clnt, server, &msg, &args.seq_args,
|
||||
&res.seq_res, RPC_TASK_NO_ROUND_ROBIN);
|
||||
nfs4_init_sequence(&args.seq_args, &res.seq_res, 0, 0);
|
||||
status = nfs4_call_sync_custom(&task_setup);
|
||||
dprintk("<-- %s status=%d\n", __func__, status);
|
||||
|
||||
put_cred(cred);
|
||||
|
@@ -1015,22 +1015,6 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool nfs4_refresh_open_stateid(nfs4_stateid *dst, struct nfs4_state *state)
|
||||
{
|
||||
bool ret;
|
||||
int seq;
|
||||
|
||||
do {
|
||||
ret = false;
|
||||
seq = read_seqbegin(&state->seqlock);
|
||||
if (nfs4_state_match_open_stateid_other(state, dst)) {
|
||||
dst->seqid = state->open_stateid.seqid;
|
||||
ret = true;
|
||||
}
|
||||
} while (read_seqretry(&state->seqlock, seq));
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool nfs4_copy_open_stateid(nfs4_stateid *dst, struct nfs4_state *state)
|
||||
{
|
||||
bool ret;
|
||||
@@ -2095,8 +2079,10 @@ static int nfs4_try_migration(struct nfs_server *server, const struct cred *cred
|
||||
}
|
||||
|
||||
status = nfs4_begin_drain_session(clp);
|
||||
if (status != 0)
|
||||
return status;
|
||||
if (status != 0) {
|
||||
result = status;
|
||||
goto out;
|
||||
}
|
||||
|
||||
status = nfs4_replace_transport(server, locations);
|
||||
if (status != 0) {
|
||||
|
@@ -1174,7 +1174,7 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap,
|
||||
} else
|
||||
*p++ = cpu_to_be32(NFS4_SET_TO_SERVER_TIME);
|
||||
}
|
||||
if (bmval[2] & FATTR4_WORD2_SECURITY_LABEL) {
|
||||
if (label && (bmval[2] & FATTR4_WORD2_SECURITY_LABEL)) {
|
||||
*p++ = cpu_to_be32(label->lfs);
|
||||
*p++ = cpu_to_be32(label->pi);
|
||||
*p++ = cpu_to_be32(label->len);
|
||||
|
@@ -359,9 +359,10 @@ pnfs_clear_lseg_state(struct pnfs_layout_segment *lseg,
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the seqid of a layout stateid
|
||||
* Update the seqid of a layout stateid after receiving
|
||||
* NFS4ERR_OLD_STATEID
|
||||
*/
|
||||
bool nfs4_layoutreturn_refresh_stateid(nfs4_stateid *dst,
|
||||
bool nfs4_layout_refresh_old_stateid(nfs4_stateid *dst,
|
||||
struct pnfs_layout_range *dst_range,
|
||||
struct inode *inode)
|
||||
{
|
||||
@@ -377,7 +378,15 @@ bool nfs4_layoutreturn_refresh_stateid(nfs4_stateid *dst,
|
||||
|
||||
spin_lock(&inode->i_lock);
|
||||
lo = NFS_I(inode)->layout;
|
||||
if (lo && nfs4_stateid_match_other(dst, &lo->plh_stateid)) {
|
||||
if (lo && pnfs_layout_is_valid(lo) &&
|
||||
nfs4_stateid_match_other(dst, &lo->plh_stateid)) {
|
||||
/* Is our call using the most recent seqid? If so, bump it */
|
||||
if (!nfs4_stateid_is_newer(&lo->plh_stateid, dst)) {
|
||||
nfs4_stateid_seqid_inc(dst);
|
||||
ret = true;
|
||||
goto out;
|
||||
}
|
||||
/* Try to update the seqid to the most recent */
|
||||
err = pnfs_mark_matching_lsegs_return(lo, &head, &range, 0);
|
||||
if (err != -EBUSY) {
|
||||
dst->seqid = lo->plh_stateid.seqid;
|
||||
@@ -385,6 +394,7 @@ bool nfs4_layoutreturn_refresh_stateid(nfs4_stateid *dst,
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
out:
|
||||
spin_unlock(&inode->i_lock);
|
||||
pnfs_free_lseg_list(&head);
|
||||
return ret;
|
||||
@@ -1440,6 +1450,52 @@ out_noroc:
|
||||
return false;
|
||||
}
|
||||
|
||||
int pnfs_roc_done(struct rpc_task *task, struct inode *inode,
|
||||
struct nfs4_layoutreturn_args **argpp,
|
||||
struct nfs4_layoutreturn_res **respp,
|
||||
int *ret)
|
||||
{
|
||||
struct nfs4_layoutreturn_args *arg = *argpp;
|
||||
int retval = -EAGAIN;
|
||||
|
||||
if (!arg)
|
||||
return 0;
|
||||
/* Handle Layoutreturn errors */
|
||||
switch (*ret) {
|
||||
case 0:
|
||||
retval = 0;
|
||||
break;
|
||||
case -NFS4ERR_NOMATCHING_LAYOUT:
|
||||
/* Was there an RPC level error? If not, retry */
|
||||
if (task->tk_rpc_status == 0)
|
||||
break;
|
||||
/* If the call was not sent, let caller handle it */
|
||||
if (!RPC_WAS_SENT(task))
|
||||
return 0;
|
||||
/*
|
||||
* Otherwise, assume the call succeeded and
|
||||
* that we need to release the layout
|
||||
*/
|
||||
*ret = 0;
|
||||
(*respp)->lrs_present = 0;
|
||||
retval = 0;
|
||||
break;
|
||||
case -NFS4ERR_DELAY:
|
||||
/* Let the caller handle the retry */
|
||||
*ret = -NFS4ERR_NOMATCHING_LAYOUT;
|
||||
return 0;
|
||||
case -NFS4ERR_OLD_STATEID:
|
||||
if (!nfs4_layout_refresh_old_stateid(&arg->stateid,
|
||||
&arg->range, inode))
|
||||
break;
|
||||
*ret = -NFS4ERR_NOMATCHING_LAYOUT;
|
||||
return -EAGAIN;
|
||||
}
|
||||
*argpp = NULL;
|
||||
*respp = NULL;
|
||||
return retval;
|
||||
}
|
||||
|
||||
void pnfs_roc_release(struct nfs4_layoutreturn_args *args,
|
||||
struct nfs4_layoutreturn_res *res,
|
||||
int ret)
|
||||
@@ -1449,10 +1505,15 @@ void pnfs_roc_release(struct nfs4_layoutreturn_args *args,
|
||||
const nfs4_stateid *res_stateid = NULL;
|
||||
struct nfs4_xdr_opaque_data *ld_private = args->ld_private;
|
||||
|
||||
if (ret == 0) {
|
||||
arg_stateid = &args->stateid;
|
||||
switch (ret) {
|
||||
case -NFS4ERR_NOMATCHING_LAYOUT:
|
||||
break;
|
||||
case 0:
|
||||
if (res->lrs_present)
|
||||
res_stateid = &res->stateid;
|
||||
/* Fallthrough */
|
||||
default:
|
||||
arg_stateid = &args->stateid;
|
||||
}
|
||||
pnfs_layoutreturn_free_lsegs(lo, arg_stateid, &args->range,
|
||||
res_stateid);
|
||||
|
@@ -261,7 +261,7 @@ int pnfs_destroy_layouts_byfsid(struct nfs_client *clp,
|
||||
bool is_recall);
|
||||
int pnfs_destroy_layouts_byclid(struct nfs_client *clp,
|
||||
bool is_recall);
|
||||
bool nfs4_layoutreturn_refresh_stateid(nfs4_stateid *dst,
|
||||
bool nfs4_layout_refresh_old_stateid(nfs4_stateid *dst,
|
||||
struct pnfs_layout_range *dst_range,
|
||||
struct inode *inode);
|
||||
void pnfs_put_layout_hdr(struct pnfs_layout_hdr *lo);
|
||||
@@ -282,6 +282,10 @@ bool pnfs_roc(struct inode *ino,
|
||||
struct nfs4_layoutreturn_args *args,
|
||||
struct nfs4_layoutreturn_res *res,
|
||||
const struct cred *cred);
|
||||
int pnfs_roc_done(struct rpc_task *task, struct inode *inode,
|
||||
struct nfs4_layoutreturn_args **argpp,
|
||||
struct nfs4_layoutreturn_res **respp,
|
||||
int *ret);
|
||||
void pnfs_roc_release(struct nfs4_layoutreturn_args *args,
|
||||
struct nfs4_layoutreturn_res *res,
|
||||
int ret);
|
||||
@@ -701,6 +705,15 @@ pnfs_roc(struct inode *ino,
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline int
|
||||
pnfs_roc_done(struct rpc_task *task, struct inode *inode,
|
||||
struct nfs4_layoutreturn_args **argpp,
|
||||
struct nfs4_layoutreturn_res **respp,
|
||||
int *ret)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
pnfs_roc_release(struct nfs4_layoutreturn_args *args,
|
||||
struct nfs4_layoutreturn_res *res,
|
||||
@@ -785,7 +798,7 @@ static inline void nfs4_pnfs_v3_ds_connect_unload(void)
|
||||
{
|
||||
}
|
||||
|
||||
static inline bool nfs4_layoutreturn_refresh_stateid(nfs4_stateid *dst,
|
||||
static inline bool nfs4_layout_refresh_old_stateid(nfs4_stateid *dst,
|
||||
struct pnfs_layout_range *dst_range,
|
||||
struct inode *inode)
|
||||
{
|
||||
|
@@ -2645,6 +2645,13 @@ int nfs_clone_sb_security(struct super_block *s, struct dentry *mntroot,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_clone_sb_security);
|
||||
|
||||
static void nfs_set_readahead(struct backing_dev_info *bdi,
|
||||
unsigned long iomax_pages)
|
||||
{
|
||||
bdi->ra_pages = VM_READAHEAD_PAGES;
|
||||
bdi->io_pages = iomax_pages;
|
||||
}
|
||||
|
||||
struct dentry *nfs_fs_mount_common(struct nfs_server *server,
|
||||
int flags, const char *dev_name,
|
||||
struct nfs_mount_info *mount_info,
|
||||
@@ -2687,7 +2694,7 @@ struct dentry *nfs_fs_mount_common(struct nfs_server *server,
|
||||
mntroot = ERR_PTR(error);
|
||||
goto error_splat_super;
|
||||
}
|
||||
s->s_bdi->ra_pages = server->rpages * NFS_MAX_READAHEAD;
|
||||
nfs_set_readahead(s->s_bdi, server->rpages);
|
||||
server->super = s;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user