Commit 2ec20f48 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'nfs-for-5.16-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs

Pull NFS client updates from Trond Myklebust:
 "Highlights include:

  Features:
   - NFSv4.1 can always retrieve and cache the ACCESS mode on OPEN
   - Optimisations for READDIR and the 'ls -l' style workload
   - Further replacements of dprintk() with tracepoints and other
     tracing improvements
   - Ensure we re-probe NFSv4 server capabilities when the user does a
     "mount -o remount"

  Bugfixes:
   - Fix an Oops in pnfs_mark_request_commit()
   - Fix up deadlocks in the commit code
   - Fix regressions in NFSv2/v3 attribute revalidation due to the
     change_attr_type optimisations
   - Fix some dentry verifier races
   - Fix some missing dentry verifier settings
   - Fix a performance regression in nfs_set_open_stateid_locked()
   - SUNRPC was sending multiple SYN calls when re-establishing a TCP
     connection.
   - Fix multiple NFSv4 issues due to missing sanity checking of server
     return values
   - Fix a potential Oops when FREE_STATEID races with an unmount

  Cleanups:
   - Clean up the labelled NFS code
   - Remove unused header <linux/pnfs_osd_xdr.h>"

* tag 'nfs-for-5.16-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: (84 commits)
  NFSv4: Sanity check the parameters in nfs41_update_target_slotid()
  NFS: Remove the nfs4_label argument from decode_getattr_*() functions
  NFS: Remove the nfs4_label argument from nfs_setsecurity
  NFS: Remove the nfs4_label argument from nfs_fhget()
  NFS: Remove the nfs4_label argument from nfs_add_or_obtain()
  NFS: Remove the nfs4_label argument from nfs_instantiate()
  NFS: Remove the nfs4_label from the nfs_setattrres
  NFS: Remove the nfs4_label from the nfs4_getattr_res
  NFS: Remove the f_label from the nfs4_opendata and nfs_openres
  NFS: Remove the nfs4_label from the nfs4_lookupp_res struct
  NFS: Remove the label from the nfs4_lookup_res struct
  NFS: Remove the nfs4_label from the nfs4_link_res struct
  NFS: Remove the nfs4_label from the nfs4_create_res struct
  NFS: Remove the nfs4_label from the nfs_entry struct
  NFS: Create a new nfs_alloc_fattr_with_label() function
  NFS: Always initialise fattr->label in nfs_fattr_alloc()
  NFSv4.2: alloc_file_pseudo() takes an open flag, not an f_mode
  NFS: Don't allocate nfs_fattr on the stack in __nfs42_ssc_open()
  NFSv4: Remove unnecessary 'minor version' check
  NFSv4: Fix potential Oops in decode_op_map()
  ...
parents 5147da90 f96f8cc4
......@@ -794,9 +794,6 @@ static void nlmclnt_cancel_callback(struct rpc_task *task, void *data)
goto retry_cancel;
}
dprintk("lockd: cancel status %u (task %u)\n",
status, task->tk_pid);
switch (status) {
case NLM_LCK_GRANTED:
case NLM_LCK_DENIED_GRACE_PERIOD:
......
......@@ -269,8 +269,6 @@ nlm4svc_proc_granted(struct svc_rqst *rqstp)
*/
static void nlm4svc_callback_exit(struct rpc_task *task, void *data)
{
dprintk("lockd: %5u callback returned %d\n", task->tk_pid,
-task->tk_status);
}
static void nlm4svc_callback_release(void *data)
......
......@@ -301,8 +301,6 @@ nlmsvc_proc_granted(struct svc_rqst *rqstp)
*/
static void nlmsvc_callback_exit(struct rpc_task *task, void *data)
{
dprintk("lockd: %5u callback returned %d\n", task->tk_pid,
-task->tk_status);
}
void nlmsvc_release_call(struct nlm_rqst *call)
......
......@@ -739,6 +739,9 @@ __be32 nfs4_callback_offload(void *data, void *dummy,
kfree(copy);
spin_unlock(&cps->clp->cl_lock);
trace_nfs4_cb_offload(&args->coa_fh, &args->coa_stateid,
args->wr_count, args->error,
args->wr_writeverf.committed);
return 0;
}
#endif /* CONFIG_NFS_V4_2 */
......@@ -828,7 +828,7 @@ static void nfs_server_set_fsinfo(struct nfs_server *server,
/*
* Probe filesystem information, including the FSID on v2/v3
*/
int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *mntfh, struct nfs_fattr *fattr)
static int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *mntfh, struct nfs_fattr *fattr)
{
struct nfs_fsinfo fsinfo;
struct nfs_client *clp = server->nfs_client;
......@@ -862,7 +862,30 @@ int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *mntfh, struct nfs
return 0;
}
EXPORT_SYMBOL_GPL(nfs_probe_fsinfo);
/*
* Grab the destination's particulars, including lease expiry time.
*
* Returns zero if probe succeeded and retrieved FSID matches the FSID
* we have cached.
*/
int nfs_probe_server(struct nfs_server *server, struct nfs_fh *mntfh)
{
struct nfs_fattr *fattr;
int error;
fattr = nfs_alloc_fattr();
if (fattr == NULL)
return -ENOMEM;
/* Sanity: the probe won't work if the destination server
* does not recognize the migrated FH. */
error = nfs_probe_fsinfo(server, mntfh, fattr);
nfs_free_fattr(fattr);
return error;
}
EXPORT_SYMBOL_GPL(nfs_probe_server);
/*
* Copy useful information when duplicating a server record
......@@ -1025,7 +1048,7 @@ struct nfs_server *nfs_create_server(struct fs_context *fc)
if (!(fattr->valid & NFS_ATTR_FATTR)) {
error = ctx->nfs_mod->rpc_ops->getattr(server, ctx->mntfh,
fattr, NULL, NULL);
fattr, NULL);
if (error < 0) {
dprintk("nfs_create_server: getattr error = %d\n", -error);
goto error;
......@@ -1058,7 +1081,6 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source,
rpc_authflavor_t flavor)
{
struct nfs_server *server;
struct nfs_fattr *fattr_fsinfo;
int error;
server = nfs_alloc_server();
......@@ -1067,11 +1089,6 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source,
server->cred = get_cred(source->cred);
error = -ENOMEM;
fattr_fsinfo = nfs_alloc_fattr();
if (fattr_fsinfo == NULL)
goto out_free_server;
/* Copy data from the source */
server->nfs_client = source->nfs_client;
server->destroy = source->destroy;
......@@ -1087,7 +1104,7 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source,
goto out_free_server;
/* probe the filesystem info for this server filesystem */
error = nfs_probe_fsinfo(server, fh, fattr_fsinfo);
error = nfs_probe_server(server, fh);
if (error < 0)
goto out_free_server;
......@@ -1101,11 +1118,9 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source,
nfs_server_insert_lists(server);
server->mount_time = jiffies;
nfs_free_fattr(fattr_fsinfo);
return server;
out_free_server:
nfs_free_fattr(fattr_fsinfo);
nfs_free_server(server);
return ERR_PTR(error);
}
......
......@@ -755,11 +755,13 @@ int nfs4_inode_return_delegation(struct inode *inode)
struct nfs_delegation *delegation;
delegation = nfs_start_delegation_return(nfsi);
/* Synchronous recall of any application leases */
break_lease(inode, O_WRONLY | O_RDWR);
nfs_wb_all(inode);
if (delegation != NULL)
if (delegation != NULL) {
/* Synchronous recall of any application leases */
break_lease(inode, O_WRONLY | O_RDWR);
if (S_ISREG(inode->i_mode))
nfs_wb_all(inode);
return nfs_end_delegation_return(inode, delegation, 1);
}
return 0;
}
......
This diff is collapsed.
......@@ -620,7 +620,7 @@ static void nfs_direct_commit_complete(struct nfs_commit_data *data)
nfs_unlock_and_release_request(req);
}
if (atomic_dec_and_test(&cinfo.mds->rpcs_out))
if (nfs_commit_end(cinfo.mds))
nfs_direct_write_complete(dreq);
}
......
......@@ -64,7 +64,6 @@ static struct dentry *
nfs_fh_to_dentry(struct super_block *sb, struct fid *fid,
int fh_len, int fh_type)
{
struct nfs4_label *label = NULL;
struct nfs_fattr *fattr = NULL;
struct nfs_fh *server_fh = nfs_exp_embedfh(fid->raw);
size_t fh_size = offsetof(struct nfs_fh, data) + server_fh->size;
......@@ -79,7 +78,7 @@ nfs_fh_to_dentry(struct super_block *sb, struct fid *fid,
if (fh_len < len || fh_type != len)
return NULL;
fattr = nfs_alloc_fattr();
fattr = nfs_alloc_fattr_with_label(NFS_SB(sb));
if (fattr == NULL) {
dentry = ERR_PTR(-ENOMEM);
goto out;
......@@ -95,28 +94,19 @@ nfs_fh_to_dentry(struct super_block *sb, struct fid *fid,
if (inode)
goto out_found;
label = nfs4_label_alloc(NFS_SB(sb), GFP_KERNEL);
if (IS_ERR(label)) {
dentry = ERR_CAST(label);
goto out_free_fattr;
}
rpc_ops = NFS_SB(sb)->nfs_client->rpc_ops;
ret = rpc_ops->getattr(NFS_SB(sb), server_fh, fattr, label, NULL);
ret = rpc_ops->getattr(NFS_SB(sb), server_fh, fattr, NULL);
if (ret) {
dprintk("%s: getattr failed %d\n", __func__, ret);
trace_nfs_fh_to_dentry(sb, server_fh, fattr->fileid, ret);
dentry = ERR_PTR(ret);
goto out_free_label;
goto out_free_fattr;
}
inode = nfs_fhget(sb, server_fh, fattr, label);
inode = nfs_fhget(sb, server_fh, fattr);
out_found:
dentry = d_obtain_alias(inode);
out_free_label:
nfs4_label_free(label);
out_free_fattr:
nfs_free_fattr(fattr);
out:
......@@ -131,7 +121,6 @@ nfs_get_parent(struct dentry *dentry)
struct super_block *sb = inode->i_sb;
struct nfs_server *server = NFS_SB(sb);
struct nfs_fattr *fattr = NULL;
struct nfs4_label *label = NULL;
struct dentry *parent;
struct nfs_rpc_ops const *ops = server->nfs_client->rpc_ops;
struct nfs_fh fh;
......@@ -139,31 +128,20 @@ nfs_get_parent(struct dentry *dentry)
if (!ops->lookupp)
return ERR_PTR(-EACCES);
fattr = nfs_alloc_fattr();
if (fattr == NULL) {
parent = ERR_PTR(-ENOMEM);
goto out;
}
fattr = nfs_alloc_fattr_with_label(server);
if (fattr == NULL)
return ERR_PTR(-ENOMEM);
label = nfs4_label_alloc(server, GFP_KERNEL);
if (IS_ERR(label)) {
parent = ERR_CAST(label);
goto out_free_fattr;
}
ret = ops->lookupp(inode, &fh, fattr, label);
ret = ops->lookupp(inode, &fh, fattr);
if (ret) {
parent = ERR_PTR(ret);
goto out_free_label;
goto out;
}
pinode = nfs_fhget(sb, &fh, fattr, label);
pinode = nfs_fhget(sb, &fh, fattr);
parent = d_obtain_alias(pinode);
out_free_label:
nfs4_label_free(label);
out_free_fattr:
nfs_free_fattr(fattr);
out:
nfs_free_fattr(fattr);
return parent;
}
......
......@@ -293,8 +293,6 @@ static void filelayout_read_call_done(struct rpc_task *task, void *data)
{
struct nfs_pgio_header *hdr = data;
dprintk("--> %s task->tk_status %d\n", __func__, task->tk_status);
if (test_bit(NFS_IOHDR_REDO, &hdr->flags) &&
task->tk_status == 0) {
nfs41_sequence_done(task, &hdr->res.seq_res);
......
......@@ -1414,8 +1414,6 @@ static void ff_layout_read_call_done(struct rpc_task *task, void *data)
{
struct nfs_pgio_header *hdr = data;
dprintk("--> %s task->tk_status %d\n", __func__, task->tk_status);
if (test_bit(NFS_IOHDR_REDO, &hdr->flags) &&
task->tk_status == 0) {
nfs4_sequence_done(task, &hdr->res.seq_res);
......
......@@ -378,10 +378,10 @@ nfs4_ff_layout_prepare_ds(struct pnfs_layout_segment *lseg,
goto noconnect;
ds = mirror->mirror_ds->ds;
if (READ_ONCE(ds->ds_clp))
goto out;
/* matching smp_wmb() in _nfs4_pnfs_v3/4_ds_connect */
smp_rmb();
if (ds->ds_clp)
goto out;
/* FIXME: For now we assume the server sent only one version of NFS
* to use for the DS.
......
......@@ -80,31 +80,28 @@ int nfs_get_root(struct super_block *s, struct fs_context *fc)
goto out;
/* get the actual root for this mount */
fsinfo.fattr = nfs_alloc_fattr();
fsinfo.fattr = nfs_alloc_fattr_with_label(server);
if (fsinfo.fattr == NULL)
goto out_name;
fsinfo.fattr->label = nfs4_label_alloc(server, GFP_KERNEL);
if (IS_ERR(fsinfo.fattr->label))
goto out_fattr;
error = server->nfs_client->rpc_ops->getroot(server, ctx->mntfh, &fsinfo);
if (error < 0) {
dprintk("nfs_get_root: getattr error = %d\n", -error);
nfs_errorf(fc, "NFS: Couldn't getattr on root");
goto out_label;
goto out_fattr;
}
inode = nfs_fhget(s, ctx->mntfh, fsinfo.fattr, NULL);
inode = nfs_fhget(s, ctx->mntfh, fsinfo.fattr);
if (IS_ERR(inode)) {
dprintk("nfs_get_root: get root inode failed\n");
error = PTR_ERR(inode);
nfs_errorf(fc, "NFS: Couldn't get root inode");
goto out_label;
goto out_fattr;
}
error = nfs_superblock_set_dummy_root(s, inode);
if (error != 0)
goto out_label;
goto out_fattr;
/* root dentries normally start off anonymous and get spliced in later
* if the dentry tree reaches them; however if the dentry already
......@@ -115,7 +112,7 @@ int nfs_get_root(struct super_block *s, struct fs_context *fc)
dprintk("nfs_get_root: get root dentry failed\n");
error = PTR_ERR(root);
nfs_errorf(fc, "NFS: Couldn't get root dentry");
goto out_label;
goto out_fattr;
}
security_d_instantiate(root, inode);
......@@ -151,11 +148,9 @@ int nfs_get_root(struct super_block *s, struct fs_context *fc)
!(kflags_out & SECURITY_LSM_NATIVE_LABELS))
server->caps &= ~NFS_CAP_SECURITY_LABEL;
nfs_setsecurity(inode, fsinfo.fattr, fsinfo.fattr->label);
nfs_setsecurity(inode, fsinfo.fattr);
error = 0;
out_label:
nfs4_label_free(fsinfo.fattr->label);
out_fattr:
nfs_free_fattr(fsinfo.fattr);
out_name:
......@@ -165,5 +160,5 @@ int nfs_get_root(struct super_block *s, struct fs_context *fc)
error_splat_root:
dput(fc->root);
fc->root = NULL;
goto out_label;
goto out_fattr;
}
This diff is collapsed.
......@@ -193,7 +193,7 @@ extern void nfs_clients_exit(struct net *net);
extern struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *);
int nfs_create_rpc_client(struct nfs_client *, const struct nfs_client_initdata *, rpc_authflavor_t);
struct nfs_client *nfs_get_client(const struct nfs_client_initdata *);
int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *, struct nfs_fattr *);
int nfs_probe_server(struct nfs_server *, struct nfs_fh *);
void nfs_server_insert_lists(struct nfs_server *);
void nfs_server_remove_lists(struct nfs_server *);
void nfs_init_timeout_values(struct rpc_timeout *to, int proto, int timeo, int retrans);
......@@ -209,6 +209,7 @@ extern struct nfs_client *
nfs4_find_client_sessionid(struct net *, const struct sockaddr *,
struct nfs4_sessionid *, u32);
extern struct nfs_server *nfs_create_server(struct fs_context *);
extern void nfs4_server_set_init_caps(struct nfs_server *);
extern struct nfs_server *nfs4_create_server(struct fs_context *);
extern struct nfs_server *nfs4_create_referral_server(struct fs_context *);
extern int nfs4_update_server(struct nfs_server *server, const char *hostname,
......@@ -341,14 +342,6 @@ nfs4_label_copy(struct nfs4_label *dst, struct nfs4_label *src)
return dst;
}
static inline void nfs4_label_free(struct nfs4_label *label)
{
if (label) {
kfree(label->label);
kfree(label);
}
return;
}
static inline void nfs_zap_label_cache_locked(struct nfs_inode *nfsi)
{
......@@ -357,7 +350,6 @@ static inline void nfs_zap_label_cache_locked(struct nfs_inode *nfsi)
}
#else
static inline struct nfs4_label *nfs4_label_alloc(struct nfs_server *server, gfp_t flags) { return NULL; }
static inline void nfs4_label_free(void *label) {}
static inline void nfs_zap_label_cache_locked(struct nfs_inode *nfsi)
{
}
......
......@@ -308,8 +308,7 @@ int nfs_submount(struct fs_context *fc, struct nfs_server *server)
/* Look it up again to get its attributes */
err = server->nfs_client->rpc_ops->lookup(d_inode(parent), dentry,
ctx->mntfh, ctx->clone_data.fattr,
NULL);
ctx->mntfh, ctx->clone_data.fattr);
dput(parent);
if (err != 0)
return err;
......
......@@ -100,8 +100,7 @@ nfs3_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
*/
static int
nfs3_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
struct nfs_fattr *fattr, struct nfs4_label *label,
struct inode *inode)
struct nfs_fattr *fattr, struct inode *inode)
{
struct rpc_message msg = {
.rpc_proc = &nfs3_procedures[NFS3PROC_GETATTR],
......@@ -193,8 +192,7 @@ __nfs3_proc_lookup(struct inode *dir, const char *name, size_t len,
static int
nfs3_proc_lookup(struct inode *dir, struct dentry *dentry,
struct nfs_fh *fhandle, struct nfs_fattr *fattr,
struct nfs4_label *label)
struct nfs_fh *fhandle, struct nfs_fattr *fattr)
{
unsigned short task_flags = 0;
......@@ -209,7 +207,7 @@ nfs3_proc_lookup(struct inode *dir, struct dentry *dentry,
}
static int nfs3_proc_lookupp(struct inode *inode, struct nfs_fh *fhandle,
struct nfs_fattr *fattr, struct nfs4_label *label)
struct nfs_fattr *fattr)
{
const char dotdot[] = "..";
const size_t len = strlen(dotdot);
......@@ -323,7 +321,7 @@ nfs3_do_create(struct inode *dir, struct dentry *dentry, struct nfs3_createdata
if (status != 0)
return ERR_PTR(status);
return nfs_add_or_obtain(dentry, data->res.fh, data->res.fattr, NULL);
return nfs_add_or_obtain(dentry, data->res.fh, data->res.fattr);
}
static void nfs3_free_createdata(struct nfs3_createdata *data)
......
......@@ -2227,7 +2227,7 @@ static int decode_fsinfo3resok(struct xdr_stream *xdr,
/* ignore properties */
result->lease_time = 0;
result->change_attr_type = NFS4_CHANGE_TYPE_IS_TIME_METADATA;
result->change_attr_type = NFS4_CHANGE_TYPE_IS_UNDEFINED;
return 0;
}
......
......@@ -83,6 +83,10 @@ static int _nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep,
status = nfs_post_op_update_inode_force_wcc(inode,
res.falloc_fattr);
if (msg->rpc_proc == &nfs4_procedures[NFSPROC4_CLNT_ALLOCATE])
trace_nfs4_fallocate(inode, &args, status);
else
trace_nfs4_deallocate(inode, &args, status);
kfree(res.falloc_fattr);
return status;
}
......@@ -363,6 +367,7 @@ static ssize_t _nfs42_proc_copy(struct file *src,
status = nfs4_call_sync(dst_server->client, dst_server, &msg,
&args->seq_args, &res->seq_res, 0);
trace_nfs4_copy(src_inode, dst_inode, args, res, nss, status);
if (status == -ENOTSUPP)
dst_server->caps &= ~NFS_CAP_COPY;
if (status)
......@@ -504,6 +509,7 @@ static void nfs42_offload_cancel_done(struct rpc_task *task, void *calldata)
{
struct nfs42_offloadcancel_data *data = calldata;
trace_nfs4_offload_cancel(&data->args, task->tk_status);
nfs41_sequence_done(task, &data->res.osr_seq_res);
if (task->tk_status &&
nfs4_async_handle_error(task, data->seq_server, NULL,
......@@ -598,6 +604,7 @@ static int _nfs42_proc_copy_notify(struct file *src, struct file *dst,
status = nfs4_call_sync(src_server->client, src_server, &msg,
&args->cna_seq_args, &res->cnr_seq_res, 0);
trace_nfs4_copy_notify(file_inode(src), args, res, status);
if (status == -ENOTSUPP)
src_server->caps &= ~NFS_CAP_COPY_NOTIFY;
......@@ -678,6 +685,7 @@ static loff_t _nfs42_proc_llseek(struct file *filep,
status = nfs4_call_sync(server->client, server, &msg,
&args.seq_args, &res.seq_res, 0);
trace_nfs4_llseek(inode, &args, &res, status);
if (status == -ENOTSUPP)
server->caps &= ~NFS_CAP_SEEK;
if (status)
......@@ -1071,6 +1079,7 @@ static int _nfs42_proc_clone(struct rpc_message *msg, struct file *src_f,
status = nfs4_call_sync(server->client, server, msg,
&args.seq_args, &res.seq_res, 0);
trace_nfs4_clone(src_inode, dst_inode, &args, status);
if (status == 0) {
nfs42_copy_dest_done(dst_inode, dst_offset, count);
status = nfs_post_op_update_inode(dst_inode, res.dst_fattr);
......
......@@ -234,7 +234,6 @@ struct nfs4_opendata {
struct nfs4_string group_name;
struct nfs4_label *a_label;
struct nfs_fattr f_attr;
struct nfs4_label *f_label;
struct dentry *dir;
struct dentry *dentry;
struct nfs4_state_owner *owner;
......@@ -317,8 +316,7 @@ extern int nfs4_set_rw_stateid(nfs4_stateid *stateid,
const struct nfs_lock_context *l_ctx,
fmode_t fmode);
extern int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
struct nfs_fattr *fattr, struct nfs4_label *label,
struct inode *inode);
struct nfs_fattr *fattr, struct inode *inode);
extern int update_open_stateid(struct nfs4_state *state,
const nfs4_stateid *open_stateid,
const nfs4_stateid *deleg_stateid,
......
......@@ -1059,31 +1059,15 @@ static void nfs4_session_limit_xasize(struct nfs_server *server)
#endif
}
static int nfs4_server_common_setup(struct nfs_server *server,
struct nfs_fh *mntfh, bool auth_probe)
void nfs4_server_set_init_caps(struct nfs_server *server)
{
struct nfs_fattr *fattr;
int error;
/* data servers support only a subset of NFSv4.1 */
if (is_ds_only_client(server->nfs_client))
return -EPROTONOSUPPORT;
fattr = nfs_alloc_fattr();
if (fattr == NULL)
return -ENOMEM;
/* We must ensure the session is initialised first */
error = nfs4_init_session(server->nfs_client);
if (error < 0)
goto out;
/* Set the basic capabilities */
server->caps |= server->nfs_client->cl_mvops->init_caps;
if (server->flags & NFS_MOUNT_NORDIRPLUS)
server->caps &= ~NFS_CAP_READDIRPLUS;
if (server->nfs_client->cl_proto == XPRT_TRANSPORT_RDMA)
server->caps &= ~NFS_CAP_READ_PLUS;
/*
* Don't use NFS uid/gid mapping if we're using AUTH_SYS or lower
* authentication.
......@@ -1091,7 +1075,23 @@ static int nfs4_server_common_setup(struct nfs_server *server,
if (nfs4_disable_idmapping &&
server->client->cl_auth->au_flavor == RPC_AUTH_UNIX)
server->caps |= NFS_CAP_UIDGID_NOMAP;
}
static int nfs4_server_common_setup(struct nfs_server *server,
struct nfs_fh *mntfh, bool auth_probe)
{
int error;
/* data servers support only a subset of NFSv4.1 */
if (is_ds_only_client(server->nfs_client))
return -EPROTONOSUPPORT;
/* We must ensure the session is initialised first */
error = nfs4_init_session(server->nfs_client);
if (error < 0)
goto out;
nfs4_server_set_init_caps(server);
/* Probe the root fh to retrieve its FSID and filehandle */
error = nfs4_get_rootfh(server, mntfh, auth_probe);
......@@ -1103,7 +1103,7 @@ static int nfs4_server_common_setup(struct nfs_server *server,
(unsigned long long) server->fsid.minor);
nfs_display_fhandle(mntfh, "Pseudo-fs root FH");
error = nfs_probe_fsinfo(server, mntfh, fattr);
error = nfs_probe_server(server, mntfh);
if (error < 0)
goto out;
......@@ -1117,7 +1117,6 @@ static int nfs4_server_common_setup(struct nfs_server *server,
server->mount_time = jiffies;
server->destroy = nfs4_destroy_server;
out:
nfs_free_fattr(fattr);
return error;
}
......@@ -1288,30 +1287,6 @@ struct nfs_server *nfs4_create_referral_server(struct fs_context *fc)
return ERR_PTR(error);
}
/*
* Grab the destination's particulars, including lease expiry time.
*
* Returns zero if probe succeeded and retrieved FSID matches the FSID
* we have cached.
*/
static int nfs_probe_destination(struct nfs_server *server)
{
struct inode *inode = d_inode(server->super->s_root);
struct nfs_fattr *fattr;
int error;
fattr = nfs_alloc_fattr();
if (fattr == NULL)
return -ENOMEM;
/* Sanity: the probe won't work if the destination server
* does not recognize the migrated FH. */
error = nfs_probe_fsinfo(server, NFS_FH(inode), fattr);
nfs_free_fattr(fattr);
return error;
}
/**
* nfs4_update_server - Move an nfs_server to a different nfs_client
*
......@@ -1372,5 +1347,5 @@ int nfs4_update_server(struct nfs_server *server, const char *hostname,
server->nfs_client->cl_hostname = kstrdup(hostname, GFP_KERNEL);
nfs_server_insert_lists(server);
return nfs_probe_destination(server);
return nfs_probe_server(server, NFS_FH(d_inode(server->super->s_root)));
}
......@@ -317,7 +317,7 @@ static int read_name_gen = 1;
static struct file *__nfs42_ssc_open(struct vfsmount *ss_mnt,
struct nfs_fh *src_fh, nfs4_stateid *stateid)
{
struct nfs_fattr fattr;
struct nfs_fattr *fattr = nfs_alloc_fattr();
struct file *filep, *res;
struct nfs_server *server;
struct inode *r_ino = NULL;
......@@ -328,9 +328,10 @@ static struct file *__nfs42_ssc_open(struct vfsmount *ss_mnt,
server = NFS_SERVER(ss_mnt->mnt_root->d_inode);
nfs_fattr_init(&fattr);
if (!fattr)
return ERR_PTR(-ENOMEM);
status = nfs4_proc_getattr(server, src_fh, &fattr, NULL, NULL);
status = nfs4_proc_getattr(server, src_fh, fattr, NULL);
if (status < 0) {
res = ERR_PTR(status);
goto out;
......@@ -343,20 +344,18 @@ static struct file *__nfs42_ssc_open(struct vfsmount *ss_mnt,
goto out;
snprintf(read_name, len, SSC_READ_NAME_BODY, read_name_gen++);
r_ino = nfs_fhget(ss_mnt->mnt_root->d_inode->i_sb, src_fh, &fattr,
NULL);
r_ino = nfs_fhget(ss_mnt->mnt_root->d_inode->i_sb, src_fh, fattr);
if (IS_ERR(r_ino)) {
res = ERR_CAST(r_ino);
goto out_free_name;
}
filep = alloc_file_pseudo(r_ino, ss_mnt, read_name, FMODE_READ,
filep = alloc_file_pseudo(r_ino, ss_mnt, read_name, O_RDONLY,
r_ino->i_fop);
if (IS_ERR(filep)) {
res = ERR_CAST(filep);
goto out_free_name;
}
filep->f_mode |= FMODE_READ;
ctx = alloc_nfs_open_context(filep->f_path.dentry, filep->f_mode,
filep);
......@@ -388,6 +387,7 @@ static struct file *__nfs42_ssc_open(struct vfsmount *ss_mnt,
out_free_name:
kfree(read_name);
out:
nfs_free_fattr(fattr);
return res;
out_stateowner:
nfs4_put_state_owner(sp);
......
......@@ -487,7 +487,7 @@ nfs_idmap_new(struct nfs_client *clp)
err_destroy_pipe:
rpc_destroy_pipe_data(idmap->idmap_pipe);
err:
get_user_ns(idmap->user_ns);
put_user_ns(idmap->user_ns);
kfree(idmap);
return error;
}
......
This diff is collapsed.
......@@ -511,12 +511,16 @@ void nfs41_update_target_slotid(struct nfs4_slot_table *tbl,
struct nfs4_slot *slot,
struct nfs4_sequence_res *res)
{
u32 target_highest_slotid = min(res->sr_target_highest_slotid,
NFS4_MAX_SLOTID);
u32 highest_slotid = min(res->sr_highest_slotid, NFS4_MAX_SLOTID);
spin_lock(&tbl->slot_tbl_lock);
if (!nfs41_is_outlier_target_slotid(tbl, res->sr_target_highest_slotid))
nfs41_set_target_slotid_locked(tbl, res->sr_target_highest_slotid);
if (!nfs41_is_outlier_target_slotid(tbl, target_highest_slotid))
nfs41_set_target_slotid_locked(tbl, target_highest_slotid);
if (tbl->generation == slot->generation)
nfs41_set_server_slotid_locked(tbl, res->sr_highest_slotid);
nfs41_set_max_slotid_locked(tbl, res->sr_target_highest_slotid);
nfs41_set_server_slotid_locked(tbl, highest_slotid);
nfs41_set_max_slotid_locked(tbl, target_highest_slotid);
spin_unlock(&tbl->slot_tbl_lock);
}
......
......@@ -12,6 +12,7 @@
#define NFS4_DEF_SLOT_TABLE_SIZE (64U)
#define NFS4_DEF_CB_SLOT_TABLE_SIZE (16U)
#define NFS4_MAX_SLOT_TABLE (1024U)
#define NFS4_MAX_SLOTID (NFS4_MAX_SLOT_TABLE - 1U)
#define NFS4_NO_SLOT ((u32)-1)
#if IS_ENABLED(CONFIG_NFS_V4)
......
......@@ -1194,10 +1194,7 @@ static int nfs4_run_state_manager(void *);
static void nfs4_clear_state_manager_bit(struct nfs_client *clp)
{
smp_mb__before_atomic();
clear_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state);
smp_mb__after_atomic();
wake_up_bit(&clp->cl_state, NFS4CLNT_MANAGER_RUNNING);
clear_and_wake_up_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state);
rpc_wake_up(&clp->cl_rpcwaitq);
}
......
This diff is collapsed.
......@@ -3168,20 +3168,23 @@ static int decode_opaque_inline(struct xdr_stream *xdr, unsigned int *len, char
static int decode_compound_hdr(struct xdr_stream *xdr, struct compound_hdr *hdr)
{
__be32 *p;
ssize_t ret;
void *ptr;
u32 tmp;
p = xdr_inline_decode(xdr, 8);
if (unlikely(!p))
if (xdr_stream_decode_u32(xdr, &tmp) < 0)
return -EIO;
hdr->status = be32_to_cpup(p++);
hdr->taglen = be32_to_cpup(p);
hdr->status = tmp;
p = xdr_inline_decode(xdr, hdr->taglen + 4);
if (unlikely(!p))
ret = xdr_stream_decode_opaque_inline(xdr, &ptr, NFS4_OPAQUE_LIMIT);
if (ret < 0)
return -EIO;
hdr->taglen = ret;
hdr->tag = ptr;
if (xdr_stream_decode_u32(xdr, &tmp) < 0)
return -EIO;
hdr->tag = (char *)p;
p += XDR_QUADLEN(hdr->taglen);
hdr->nops = be32_to_cpup(p);
hdr->nops = tmp;
if (unlikely(hdr->nops < 1))
return nfs4_stat_to_errno(hdr->status);
return 0;
......@@ -4582,8 +4585,7 @@ static int decode_attr_mdsthreshold(struct xdr_stream *xdr,
static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap,
struct nfs_fattr *fattr, struct nfs_fh *fh,
struct nfs4_fs_locations *fs_loc, struct nfs4_label *label,
const struct nfs_server *server)
struct nfs4_fs_locations *fs_loc, const struct nfs_server *server)
{
int status;
umode_t fmode = 0;
......@@ -4698,8 +4700,8 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap,
if (status < 0)
goto xdr_error;
if (label) {
status = decode_attr_security_label(xdr, bitmap, label);
if (fattr->label) {
status = decode_attr_security_label(xdr, bitmap, fattr->label);
if (status < 0)
goto xdr_error;
fattr->valid |= status;
......@@ -4712,7 +4714,7 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap,
static int decode_getfattr_generic(struct xdr_stream *xdr, struct nfs_fattr *fattr,
struct nfs_fh *fh, struct nfs4_fs_locations *fs_loc,
struct nfs4_label *label, const struct nfs_server *server)
const struct nfs_server *server)
{
unsigned int savep;
uint32_t attrlen,
......@@ -4731,8 +4733,7 @@ static int decode_getfattr_generic(struct xdr_stream *xdr, struct nfs_fattr *fat
if (status < 0)
goto xdr_error;
status = decode_getfattr_attrs(xdr, bitmap, fattr, fh, fs_loc,
label, server);
status = decode_getfattr_attrs(xdr, bitmap, fattr, fh, fs_loc, server);
if (status < 0)
goto xdr_error;
......@@ -4742,16 +4743,10 @@ static int decode_getfattr_generic(struct xdr_stream *xdr, struct nfs_fattr *fat
return status;
}
static int decode_getfattr_label(struct xdr_stream *xdr, struct nfs_fattr *fattr,
struct nfs4_label *label, const struct nfs_server *server)
{
return decode_getfattr_generic(xdr, fattr, NULL, NULL, label, server);
}
static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr,
const struct nfs_server *server)
{
return decode_getfattr_generic(xdr, fattr, NULL, NULL, NULL, server);
return decode_getfattr_generic(xdr, fattr, NULL, NULL, server);
}
/*
......@@ -5572,20 +5567,9 @@ static int decode_secinfo_no_name(struct xdr_stream *xdr, struct nfs4_secinfo_re
static int decode_op_map(struct xdr_stream *xdr, struct nfs4_op_map *op_map)
{
__be32 *p;
uint32_t bitmap_words;
unsigned int i;
p = xdr_inline_decode(xdr, 4);
if (!p)
return -EIO;
bitmap_words = be32_to_cpup(p++);
if (bitmap_words > NFS4_OP_MAP_NUM_WORDS)
if (xdr_stream_decode_uint32_array(xdr, op_map->u.words,
ARRAY_SIZE(op_map->u.words)) < 0)
return -EIO;
p = xdr_inline_decode(xdr, 4 * bitmap_words);
for (i = 0; i < bitmap_words; i++)
op_map->u.words[i] = be32_to_cpup(p++);
return 0;
}
......@@ -6179,7 +6163,7 @@ static int nfs4_xdr_dec_lookup(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
status = decode_getfh(xdr, res->fh);
if (status)
goto out;
status = decode_getfattr_label(xdr, res->fattr, res->label, res->server);
status = decode_getfattr(xdr, res->fattr, res->server);
out:
return status;
}
......@@ -6209,7 +6193,7 @@ static int nfs4_xdr_dec_lookupp(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
status = decode_getfh(xdr, res->fh);
if (status)
goto out;
status = decode_getfattr_label(xdr, res->fattr, res->label, res->server);
status = decode_getfattr(xdr, res->fattr, res->server);
out:
return status;
}
......@@ -6236,8 +6220,7 @@ static int nfs4_xdr_dec_lookup_root(struct rpc_rqst *rqstp,
goto out;
status = decode_getfh(xdr, res->fh);
if (status == 0)
status = decode_getfattr_label(xdr, res->fattr,
res->label, res->server);
status = decode_getfattr(xdr, res->fattr, res->server);
out:
return status;
}
......@@ -6331,7 +6314,7 @@ static int nfs4_xdr_dec_link(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
status = decode_restorefh(xdr);
if (status)
goto out;
decode_getfattr_label(xdr, res->fattr, res->label, res->server);
decode_getfattr(xdr, res->fattr, res->server);
out:
return status;
}
......@@ -6361,7 +6344,7 @@ static int nfs4_xdr_dec_create(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
status = decode_getfh(xdr, res->fh);
if (status)
goto out;
decode_getfattr_label(xdr, res->fattr, res->label, res->server);
decode_getfattr(xdr, res->fattr, res->server);
out:
return status;
}
......@@ -6394,7 +6377,7 @@ static int nfs4_xdr_dec_getattr(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
status = decode_putfh(xdr);
if (status)
goto out;
status = decode_getfattr_label(xdr, res->fattr, res->label, res->server);
status = decode_getfattr(xdr, res->fattr, res->server);
out:
return status;
}
......@@ -6532,7 +6515,7 @@ static int nfs4_xdr_dec_open(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
goto out;
if (res->access_request)
decode_access(xdr, &res->access_supported, &res->access_result);
decode_getfattr_label(xdr, res->f_attr, res->f_label, res->server);
decode_getfattr(xdr, res->f_attr, res->server);
if (res->lg_res)
decode_layoutget(xdr, rqstp, res->lg_res);
out:
......@@ -6616,7 +6599,7 @@ static int nfs4_xdr_dec_setattr(struct rpc_rqst *rqstp,
status = decode_setattr(xdr);
if (status)
goto out;
decode_getfattr_label(xdr, res->fattr, res->label, res->server);
decode_getfattr(xdr, res->fattr, res->server);
out:
return status;
}
......@@ -7031,7 +7014,7 @@ static int nfs4_xdr_dec_fs_locations(struct rpc_rqst *req,
status = decode_getfattr_generic(xdr,
&res->fs_locations->fattr,
NULL, res->fs_locations,
NULL, res->fs_locations->server);
res->fs_locations->server);
if (status)
goto out;
if (res->renew)
......@@ -7044,7 +7027,7 @@ static int nfs4_xdr_dec_fs_locations(struct rpc_rqst *req,
status = decode_getfattr_generic(xdr,
&res->fs_locations->fattr,
NULL, res->fs_locations,
NULL, res->fs_locations->server);
res->fs_locations->server);
}
out:
return status;
......@@ -7475,7 +7458,7 @@ int nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,
return -EAGAIN;
if (decode_getfattr_attrs(xdr, bitmap, entry->fattr, entry->fh,
NULL, entry->label, entry->server) < 0)
NULL, entry->server) < 0)
return -EAGAIN;
if (entry->fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID)
entry->ino = entry->fattr->mounted_on_fileid;
......
This diff is collapsed.
......@@ -271,8 +271,7 @@ nfs_page_set_headlock(struct nfs_page *req)
void
nfs_page_clear_headlock(struct nfs_page *req)
{
smp_mb__before_atomic();
clear_bit(PG_HEADLOCK, &req->wb_flags);
clear_bit_unlock(PG_HEADLOCK, &req->wb_flags);
smp_mb__after_atomic();
if (!test_bit(PG_CONTENDED1, &req->wb_flags))
return;
......@@ -525,12 +524,7 @@ nfs_create_subreq(struct nfs_page *req,
*/
void nfs_unlock_request(struct nfs_page *req)
{
if (!NFS_WBACK_BUSY(req)) {
printk(KERN_ERR "NFS: Invalid unlock attempted\n");
BUG();
}
smp_mb__before_atomic();
clear_bit(PG_BUSY, &req->wb_flags);
clear_bit_unlock(PG_BUSY, &req->wb_flags);
smp_mb__after_atomic();
if (!test_bit(PG_CONTENDED2, &req->wb_flags))
return;
......@@ -870,9 +864,6 @@ static void nfs_pgio_result(struct rpc_task *task, void *calldata)
struct nfs_pgio_header *hdr = calldata;
struct inode *inode = hdr->inode;
dprintk("NFS: %s: %5u, (status %d)\n", __func__,
task->tk_pid, task->tk_status);
if (hdr->rw_ops->rw_done(task, hdr, inode) != 0)
return;
if (task->tk_status < 0)
......
......@@ -82,10 +82,6 @@ enum pnfs_try_status {
PNFS_TRY_AGAIN = 2,
};
/* error codes for internal use */
#define NFS4ERR_RESET_TO_MDS 12001
#define NFS4ERR_RESET_TO_PNFS 12002
#ifdef CONFIG_NFS_V4_1
#define LAYOUT_NFSV4_1_MODULE_PREFIX "nfs-layouttype4"
......@@ -517,7 +513,7 @@ pnfs_mark_request_commit(struct nfs_page *req, struct pnfs_layout_segment *lseg,
{
struct pnfs_ds_commit_info *fl_cinfo = cinfo->ds;
if (!lseg || !fl_cinfo->ops->mark_request_commit)
if (!lseg || !fl_cinfo->ops || !fl_cinfo->ops->mark_request_commit)
return false;
fl_cinfo->ops->mark_request_commit(req, lseg, cinfo, ds_commit_idx);
return true;
......
......@@ -468,7 +468,6 @@ pnfs_bucket_alloc_ds_commits(struct list_head *list,
goto out_error;
data->ds_commit_index = i;
list_add_tail(&data->list, list);
atomic_inc(&cinfo->mds->rpcs_out);
nreq++;
}
mutex_unlock(&NFS_I(cinfo->inode)->commit_mutex);
......@@ -520,7 +519,6 @@ pnfs_generic_commit_pagelist(struct inode *inode, struct list_head *mds_pages,
data->ds_commit_index = -1;
list_splice_init(mds_pages, &data->pages);
list_add_tail(&data->list, &list);
atomic_inc(&cinfo->mds->rpcs_out);
nreq++;
}
......@@ -895,7 +893,7 @@ static int _nfs4_pnfs_v3_ds_connect(struct nfs_server *mds_srv,
}
smp_wmb();
ds->ds_clp = clp;
WRITE_ONCE(ds->ds_clp, clp);
dprintk("%s [new] addr: %s\n", __func__, ds->ds_remotestr);
out:
return status;
......@@ -973,7 +971,7 @@ static int _nfs4_pnfs_v4_ds_connect(struct nfs_server *mds_srv,
}
smp_wmb();
ds->ds_clp = clp;
WRITE_ONCE(ds->ds_clp, clp);
dprintk("%s [new] addr: %s\n", __func__, ds->ds_remotestr);
out:
return status;
......
......@@ -91,7 +91,7 @@ nfs_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
info->dtpref = fsinfo.tsize;
info->maxfilesize = 0x7FFFFFFF;
info->lease_time = 0;
info->change_attr_type = NFS4_CHANGE_TYPE_IS_TIME_METADATA;
info->change_attr_type = NFS4_CHANGE_TYPE_IS_UNDEFINED;
return 0;
}
......@@ -100,8 +100,7 @@ nfs_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
*/
static int
nfs_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
struct nfs_fattr *fattr, struct nfs4_label *label,
struct inode *inode)
struct nfs_fattr *fattr, struct inode *inode)
{
struct rpc_message msg = {
.rpc_proc = &nfs_procedures[NFSPROC_GETATTR],
......@@ -154,8 +153,7 @@ nfs_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
static int
nfs_proc_lookup(struct inode *dir, struct dentry *dentry,
struct nfs_fh *fhandle, struct nfs_fattr *fattr,
struct nfs4_label *label)
struct nfs_fh *fhandle, struct nfs_fattr *fattr)
{
struct nfs_diropargs arg = {
.fh = NFS_FH(dir),
......@@ -257,7 +255,7 @@ nfs_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
nfs_mark_for_revalidate(dir);
if (status == 0)
status = nfs_instantiate(dentry, data->res.fh, data->res.fattr, NULL);
status = nfs_instantiate(dentry, data->res.fh, data->res.fattr);
nfs_free_createdata(data);
out:
dprintk("NFS reply create: %d\n", status);
......@@ -304,7 +302,7 @@ nfs_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
}
if (status == 0)
status = nfs_instantiate(dentry, data->res.fh, data->res.fattr, NULL);
status = nfs_instantiate(dentry, data->res.fh, data->res.fattr);
nfs_free_createdata(data);
out:
dprintk("NFS reply mknod: %d\n", status);
......@@ -436,7 +434,7 @@ nfs_proc_symlink(struct inode *dir, struct dentry *dentry, struct page *page,
* should fill in the data with a LOOKUP call on the wire.
*/
if (status == 0)
status = nfs_instantiate(dentry, fh, fattr, NULL);
status = nfs_instantiate(dentry, fh, fattr);
out_free:
nfs_free_fattr(fattr);
......@@ -465,7 +463,7 @@ nfs_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr)
status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
nfs_mark_for_revalidate(dir);
if (status == 0)
status = nfs_instantiate(dentry, data->res.fh, data->res.fattr, NULL);
status = nfs_instantiate(dentry, data->res.fh, data->res.fattr);
nfs_free_createdata(data);
out:
dprintk("NFS reply mkdir: %d\n", status);
......
......@@ -337,8 +337,7 @@ int nfs_readpage(struct file *file, struct page *page)
struct inode *inode = page_file_mapping(page)->host;
int ret;
dprintk("NFS: nfs_readpage (%p %ld@%lu)\n",
page, PAGE_SIZE, page_index(page));
trace_nfs_aop_readpage(inode, page);
nfs_inc_stats(inode, NFSIOS_VFSREADPAGE);
/*
......@@ -390,9 +389,11 @@ int nfs_readpage(struct file *file, struct page *page)
}
out:
put_nfs_open_context(desc.ctx);
trace_nfs_aop_readpage_done(inode, page, ret);
return ret;
out_unlock:
unlock_page(page);
trace_nfs_aop_readpage_done(inode, page, ret);
return ret;
}
......@@ -403,10 +404,7 @@ int nfs_readpages(struct file *file, struct address_space *mapping,
struct inode *inode = mapping->host;
int ret;
dprintk("NFS: nfs_readpages (%s/%Lu %d)\n",
inode->i_sb->s_id,
(unsigned long long)NFS_FILEID(inode),
nr_pages);
trace_nfs_aop_readahead(inode, lru_to_page(pages), nr_pages);
nfs_inc_stats(inode, NFSIOS_VFSREADPAGES);
ret = -ESTALE;
......@@ -439,6 +437,7 @@ int nfs_readpages(struct file *file, struct address_space *mapping,
read_complete:
put_nfs_open_context(desc.ctx);
out:
trace_nfs_aop_readahead_done(inode, nr_pages, ret);
return ret;
}
......
......@@ -1004,6 +1004,7 @@ int nfs_reconfigure(struct fs_context *fc)
struct nfs_fs_context *ctx = nfs_fc2context(fc);
struct super_block *sb = fc->root->d_sb;
struct nfs_server *nfss = sb->s_fs_info;
int ret;
sync_filesystem(sb);
......@@ -1028,7 +1029,11 @@ int nfs_reconfigure(struct fs_context *fc)
}
/* compare new mount options with old ones */
return nfs_compare_remount_data(nfss, ctx);
ret = nfs_compare_remount_data(nfss, ctx);
if (ret)
return ret;
return nfs_probe_server(nfss, NFS_FH(d_inode(fc->root)));
}
EXPORT_SYMBOL_GPL(nfs_reconfigure);
......
......@@ -288,6 +288,7 @@ static void nfs_grow_file(struct page *page, unsigned int offset, unsigned int c
end = page_file_offset(page) + ((loff_t)offset+count);
if (i_size >= end)
goto out;
trace_nfs_size_grow(inode, end);
i_size_write(inode, end);
NFS_I(inode)->cache_validity &= ~NFS_INO_INVALID_SIZE;
nfs_inc_stats(inode, NFSIOS_EXTENDWRITE);
......@@ -1038,25 +1039,11 @@ nfs_scan_commit_list(struct list_head *src, struct list_head *dst,
struct nfs_page *req, *tmp;
int ret = 0;
restart:
list_for_each_entry_safe(req, tmp, src, wb_list) {
kref_get(&req->wb_kref);
if (!nfs_lock_request(req)) {
int status;
/* Prevent deadlock with nfs_lock_and_join_requests */
if (!list_empty(dst)) {
nfs_release_request(req);
continue;
}
/* Ensure we make progress to prevent livelock */
mutex_unlock(&NFS_I(cinfo->inode)->commit_mutex);
status = nfs_wait_on_request(req);
nfs_release_request(req);
mutex_lock(&NFS_I(cinfo->inode)->commit_mutex);
if (status < 0)
break;
goto restart;
continue;
}
nfs_request_remove_commit_list(req, cinfo);
clear_bit(PG_COMMIT_TO_DS, &req->wb_flags);
......@@ -1246,7 +1233,7 @@ nfs_key_timeout_notify(struct file *filp, struct inode *inode)
struct nfs_open_context *ctx = nfs_file_open_context(filp);
if (nfs_ctx_key_to_expire(ctx, inode) &&
!ctx->ll_cred)
!rcu_access_pointer(ctx->ll_cred))
/* Already expired! */
return -EACCES;
return 0;
......@@ -1258,23 +1245,38 @@ nfs_key_timeout_notify(struct file *filp, struct inode *inode)
bool nfs_ctx_key_to_expire(struct nfs_open_context *ctx, struct inode *inode)
{
struct rpc_auth *auth = NFS_SERVER(inode)->client->cl_auth;
struct rpc_cred *cred = ctx->ll_cred;
struct rpc_cred *cred, *new, *old = NULL;
struct auth_cred acred = {
.cred = ctx->cred,
};
bool ret = false;
if (cred && !cred->cr_ops->crmatch(&acred, cred, 0)) {
put_rpccred(cred);
ctx->ll_cred = NULL;
cred = NULL;
}
if (!cred)
cred = auth->au_ops->lookup_cred(auth, &acred, 0);
if (!cred || IS_ERR(cred))
rcu_read_lock();
cred = rcu_dereference(ctx->ll_cred);
if (cred && !(cred->cr_ops->crkey_timeout &&
cred->cr_ops->crkey_timeout(cred)))
goto out;
rcu_read_unlock();
new = auth->au_ops->lookup_cred(auth, &acred, 0);
if (new == cred) {
put_rpccred(new);
return true;
ctx->ll_cred = cred;
return !!(cred->cr_ops->crkey_timeout &&
cred->cr_ops->crkey_timeout(cred));
}
if (IS_ERR_OR_NULL(new)) {
new = NULL;
ret = true;
} else if (new->cr_ops->crkey_timeout &&
new->cr_ops->crkey_timeout(new))
ret = true;
rcu_read_lock();
old = rcu_dereference_protected(xchg(&ctx->ll_cred,
RCU_INITIALIZER(new)), 1);
out:
rcu_read_unlock();
put_rpccred(old);
return ret;
}
/*
......@@ -1382,8 +1384,6 @@ int nfs_updatepage(struct file *file, struct page *page,
status = nfs_writepage_setup(ctx, page, offset, count);
if (status < 0)
nfs_set_pageerror(mapping);
else
__set_page_dirty_nobuffers(page);
out:
dprintk("NFS: nfs_updatepage returns %d (isize %lld)\n",
status, (long long)i_size_read(inode));
......@@ -1671,10 +1671,13 @@ static void nfs_commit_begin(struct nfs_mds_commit_info *cinfo)
atomic_inc(&cinfo->rpcs_out);
}
static void nfs_commit_end(struct nfs_mds_commit_info *cinfo)
bool nfs_commit_end(struct nfs_mds_commit_info *cinfo)
{
if (atomic_dec_and_test(&cinfo->rpcs_out))
if (atomic_dec_and_test(&cinfo->rpcs_out)) {
wake_up_var(&cinfo->rpcs_out);
return true;
}
return false;
}
void nfs_commitdata_release(struct nfs_commit_data *data)
......@@ -1774,6 +1777,7 @@ void nfs_init_commit(struct nfs_commit_data *data,
data->res.fattr = &data->fattr;
data->res.verf = &data->verf;
nfs_fattr_init(&data->fattr);
nfs_commit_begin(cinfo->mds);
}
EXPORT_SYMBOL_GPL(nfs_init_commit);
......@@ -1820,7 +1824,6 @@ nfs_commit_list(struct inode *inode, struct list_head *head, int how,
/* Set up the argument struct */
nfs_init_commit(data, head, NULL, cinfo);
atomic_inc(&cinfo->mds->rpcs_out);
if (NFS_SERVER(inode)->nfs_client->cl_minorversion)
task_flags = RPC_TASK_MOVEABLE;
return nfs_initiate_commit(NFS_CLIENT(inode), data, NFS_PROTO(inode),
......@@ -1835,9 +1838,6 @@ static void nfs_commit_done(struct rpc_task *task, void *calldata)
{
struct nfs_commit_data *data = calldata;
dprintk("NFS: %5u nfs_commit_done (status %d)\n",
task->tk_pid, task->tk_status);
/* Call the NFS version-specific code */
NFS_PROTO(data->inode)->commit_done(task, data);
trace_nfs_commit_done(task, data);
......@@ -1936,6 +1936,7 @@ static int __nfs_commit_inode(struct inode *inode, int how,
int may_wait = how & FLUSH_SYNC;
int ret, nscan;
how &= ~FLUSH_SYNC;
nfs_init_cinfo_from_inode(&cinfo, inode);
nfs_commit_begin(cinfo.mds);
for (;;) {
......
......@@ -9,6 +9,7 @@
#define _NFSD_TRACE_H
#include <linux/tracepoint.h>
#include "export.h"
#include "nfsfh.h"
......
......@@ -292,6 +292,10 @@ enum nfsstat4 {
NFS4ERR_XATTR2BIG = 10096,
};
/* error codes for internal client use */
#define NFS4ERR_RESET_TO_MDS 12001
#define NFS4ERR_RESET_TO_PNFS 12002
static inline bool seqid_mutating_err(u32 err)
{
/* See RFC 7530, section 9.1.7 */
......
......@@ -81,7 +81,7 @@ struct nfs_open_context {
fl_owner_t flock_owner;
struct dentry *dentry;
const struct cred *cred;
struct rpc_cred *ll_cred; /* low-level cred - use to check for expiry */
struct rpc_cred __rcu *ll_cred; /* low-level cred - use to check for expiry */
struct nfs4_state *state;
fmode_t mode;
......@@ -103,6 +103,7 @@ struct nfs_open_dir_context {
__be32 verf[NFS_DIR_VERIFIER_SIZE];
__u64 dir_cookie;
__u64 dup_cookie;
pgoff_t page_index;
signed char duped;
};
......@@ -154,36 +155,39 @@ struct nfs_inode {
unsigned long attrtimeo_timestamp;
unsigned long attr_gencount;
/* "Generation counter" for the attribute cache. This is
* bumped whenever we update the metadata on the
* server.
*/
unsigned long cache_change_attribute;
struct rb_root access_cache;
struct list_head access_cache_entry_lru;
struct list_head access_cache_inode_lru;
/*
* This is the cookie verifier used for NFSv3 readdir
* operations
*/
__be32 cookieverf[NFS_DIR_VERIFIER_SIZE];
atomic_long_t nrequests;
struct nfs_mds_commit_info commit_info;
union {
/* Directory */
struct {
/* "Generation counter" for the attribute cache.
* This is bumped whenever we update the metadata
* on the server.
*/
unsigned long cache_change_attribute;
/*
* This is the cookie verifier used for NFSv3 readdir
* operations
*/
__be32 cookieverf[NFS_DIR_VERIFIER_SIZE];
/* Readers: in-flight sillydelete RPC calls */
/* Writers: rmdir */
struct rw_semaphore rmdir_sem;
};
/* Regular file */
struct {
atomic_long_t nrequests;
struct nfs_mds_commit_info commit_info;
struct mutex commit_mutex;
};
};
/* Open contexts for shared mmap writes */
struct list_head open_files;
/* Readers: in-flight sillydelete RPC calls */
/* Writers: rmdir */
struct rw_semaphore rmdir_sem;
struct mutex commit_mutex;
/* track last access to cached pages */
unsigned long page_index;
#if IS_ENABLED(CONFIG_NFS_V4)
struct nfs4_cached_acl *nfs4_acl;
/* NFSv4 state */
......@@ -272,6 +276,7 @@ struct nfs4_copy_state {
#define NFS_INO_INVALIDATING (3) /* inode is being invalidated */
#define NFS_INO_FSCACHE (5) /* inode can be cached by FS-Cache */
#define NFS_INO_FSCACHE_LOCK (6) /* FS-Cache cookie management lock */
#define NFS_INO_FORCE_READDIR (7) /* force readdirplus */
#define NFS_INO_LAYOUTCOMMIT (9) /* layoutcommit required */
#define NFS_INO_LAYOUTCOMMITTING (10) /* layoutcommit inflight */
#define NFS_INO_LAYOUTSTATS (11) /* layoutstats inflight */
......@@ -383,7 +388,7 @@ extern void nfs_zap_caches(struct inode *);
extern void nfs_set_inode_stale(struct inode *inode);
extern void nfs_invalidate_atime(struct inode *);
extern struct inode *nfs_fhget(struct super_block *, struct nfs_fh *,
struct nfs_fattr *, struct nfs4_label *);
struct nfs_fattr *);
struct inode *nfs_ilookup(struct super_block *sb, struct nfs_fattr *, struct nfs_fh *);
extern int nfs_refresh_inode(struct inode *, struct nfs_fattr *);
extern int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr);
......@@ -404,8 +409,7 @@ extern int nfs_revalidate_mapping(struct inode *inode, struct address_space *map
extern int nfs_revalidate_mapping_rcu(struct inode *inode);
extern int nfs_setattr(struct user_namespace *, struct dentry *, struct iattr *);
extern void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr, struct nfs_fattr *);
extern void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr,
struct nfs4_label *label);
extern void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr);
extern struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx);
extern void put_nfs_open_context(struct nfs_open_context *ctx);
extern struct nfs_open_context *nfs_find_open_context(struct inode *inode, const struct cred *cred, fmode_t mode);
......@@ -421,9 +425,22 @@ extern void nfs_fattr_set_barrier(struct nfs_fattr *fattr);
extern unsigned long nfs_inc_attr_generation_counter(void);
extern struct nfs_fattr *nfs_alloc_fattr(void);
extern struct nfs_fattr *nfs_alloc_fattr_with_label(struct nfs_server *server);
static inline void nfs4_label_free(struct nfs4_label *label)
{
#ifdef CONFIG_NFS_V4_SECURITY_LABEL
if (label) {
kfree(label->label);
kfree(label);
}
#endif
}
static inline void nfs_free_fattr(const struct nfs_fattr *fattr)
{
if (fattr)
nfs4_label_free(fattr->label);
kfree(fattr);
}
......@@ -511,10 +528,9 @@ extern void nfs_set_verifier(struct dentry * dentry, unsigned long verf);
extern void nfs_clear_verifier_delegated(struct inode *inode);
#endif /* IS_ENABLED(CONFIG_NFS_V4) */
extern struct dentry *nfs_add_or_obtain(struct dentry *dentry,
struct nfs_fh *fh, struct nfs_fattr *fattr,
struct nfs4_label *label);
struct nfs_fh *fh, struct nfs_fattr *fattr);
extern int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fh,
struct nfs_fattr *fattr, struct nfs4_label *label);
struct nfs_fattr *fattr);
extern int nfs_may_open(struct inode *inode, const struct cred *cred, int openflags);
extern void nfs_access_zap_cache(struct inode *inode);
extern int nfs_access_get_cached(struct inode *inode, const struct cred *cred, struct nfs_access_entry *res,
......@@ -569,11 +585,14 @@ extern int nfs_wb_page_cancel(struct inode *inode, struct page* page);
extern int nfs_commit_inode(struct inode *, int);
extern struct nfs_commit_data *nfs_commitdata_alloc(bool never_fail);
extern void nfs_commit_free(struct nfs_commit_data *data);
bool nfs_commit_end(struct nfs_mds_commit_info *cinfo);
static inline int
nfs_have_writebacks(struct inode *inode)
{
return atomic_long_read(&NFS_I(inode)->nrequests) != 0;
if (S_ISREG(inode->i_mode))
return atomic_long_read(&NFS_I(inode)->nrequests) != 0;
return 0;
}
/*
......
......@@ -488,7 +488,6 @@ struct nfs_openres {
struct nfs4_change_info cinfo;
__u32 rflags;
struct nfs_fattr * f_attr;
struct nfs4_label *f_label;
struct nfs_seqid * seqid;
const struct nfs_server *server;
fmode_t delegation_type;
......@@ -753,7 +752,6 @@ struct nfs_entry {
int eof;
struct nfs_fh * fh;
struct nfs_fattr * fattr;
struct nfs4_label *label;
unsigned char d_type;
struct nfs_server * server;
};
......@@ -834,7 +832,6 @@ struct nfs_getaclres {
struct nfs_setattrres {
struct nfs4_sequence_res seq_res;
struct nfs_fattr * fattr;
struct nfs4_label *label;
const struct nfs_server * server;
};
......@@ -1041,7 +1038,6 @@ struct nfs4_create_res {
const struct nfs_server * server;
struct nfs_fh * fh;
struct nfs_fattr * fattr;
struct nfs4_label *label;
struct nfs4_change_info dir_cinfo;
};
......@@ -1066,7 +1062,6 @@ struct nfs4_getattr_res {
struct nfs4_sequence_res seq_res;
const struct nfs_server * server;
struct nfs_fattr * fattr;
struct nfs4_label *label;
};
struct nfs4_link_arg {
......@@ -1081,7 +1076,6 @@ struct nfs4_link_res {
struct nfs4_sequence_res seq_res;
const struct nfs_server * server;
struct nfs_fattr * fattr;
struct nfs4_label *label;
struct nfs4_change_info cinfo;
struct nfs_fattr * dir_attr;
};
......@@ -1098,7 +1092,6 @@ struct nfs4_lookup_res {
const struct nfs_server * server;
struct nfs_fattr * fattr;
struct nfs_fh * fh;
struct nfs4_label *label;
};
struct nfs4_lookupp_arg {
......@@ -1112,7 +1105,6 @@ struct nfs4_lookupp_res {
const struct nfs_server *server;
struct nfs_fattr *fattr;
struct nfs_fh *fh;
struct nfs4_label *label;
};
struct nfs4_lookup_root_arg {
......@@ -1738,15 +1730,13 @@ struct nfs_rpc_ops {
int (*submount) (struct fs_context *, struct nfs_server *);
int (*try_get_tree) (struct fs_context *);
int (*getattr) (struct nfs_server *, struct nfs_fh *,
struct nfs_fattr *, struct nfs4_label *,
struct inode *);
struct nfs_fattr *, struct inode *);
int (*setattr) (struct dentry *, struct nfs_fattr *,
struct iattr *);
int (*lookup) (struct inode *, struct dentry *,
struct nfs_fh *, struct nfs_fattr *,
struct nfs4_label *);
struct nfs_fh *, struct nfs_fattr *);
int (*lookupp) (struct inode *, struct nfs_fh *,
struct nfs_fattr *, struct nfs4_label *);
struct nfs_fattr *);
int (*access) (struct inode *, struct nfs_access_entry *);
int (*readlink)(struct inode *, struct page *, unsigned int,
unsigned int);
......
This diff is collapsed.
......@@ -40,6 +40,7 @@ struct rpc_clnt {
unsigned int cl_clid; /* client id */
struct list_head cl_clients; /* Global list of clients */
struct list_head cl_tasks; /* List of tasks */
atomic_t cl_pid; /* task PID counter */
spinlock_t cl_lock; /* spinlock */
struct rpc_xprt __rcu * cl_xprt; /* transport */
const struct rpc_procinfo *cl_procinfo; /* procedure info */
......
......@@ -150,25 +150,13 @@ struct rpc_task_setup {
#define RPC_TASK_MSG_PIN_WAIT 5
#define RPC_TASK_SIGNALLED 6
#define RPC_IS_RUNNING(t) test_bit(RPC_TASK_RUNNING, &(t)->tk_runstate)
#define rpc_set_running(t) set_bit(RPC_TASK_RUNNING, &(t)->tk_runstate)
#define rpc_test_and_set_running(t) \
test_and_set_bit(RPC_TASK_RUNNING, &(t)->tk_runstate)
#define rpc_clear_running(t) \
do { \
smp_mb__before_atomic(); \
clear_bit(RPC_TASK_RUNNING, &(t)->tk_runstate); \
smp_mb__after_atomic(); \
} while (0)
#define rpc_clear_running(t) clear_bit(RPC_TASK_RUNNING, &(t)->tk_runstate)
#define RPC_IS_QUEUED(t) test_bit(RPC_TASK_QUEUED, &(t)->tk_runstate)
#define rpc_set_queued(t) set_bit(RPC_TASK_QUEUED, &(t)->tk_runstate)
#define rpc_clear_queued(t) \
do { \
smp_mb__before_atomic(); \
clear_bit(RPC_TASK_QUEUED, &(t)->tk_runstate); \
smp_mb__after_atomic(); \
} while (0)
#define rpc_clear_queued(t) clear_bit(RPC_TASK_QUEUED, &(t)->tk_runstate)
#define RPC_IS_ACTIVATED(t) test_bit(RPC_TASK_ACTIVE, &(t)->tk_runstate)
......
This diff is collapsed.
This diff is collapsed.
......@@ -13,6 +13,8 @@
#include <linux/tracepoint.h>
#include <trace/events/sunrpc_base.h>
/**
** GSS-API related trace events
**/
......@@ -99,7 +101,7 @@ DECLARE_EVENT_CLASS(rpcgss_gssapi_event,
__entry->maj_stat = maj_stat;
),
TP_printk("task:%u@%u maj_stat=%s",
TP_printk(SUNRPC_TRACE_TASK_SPECIFIER " maj_stat=%s",
__entry->task_id, __entry->client_id,
__entry->maj_stat == 0 ?
"GSS_S_COMPLETE" : show_gss_status(__entry->maj_stat))
......@@ -332,7 +334,8 @@ TRACE_EVENT(rpcgss_unwrap_failed,
__entry->client_id = task->tk_client->cl_clid;
),
TP_printk("task:%u@%u", __entry->task_id, __entry->client_id)
TP_printk(SUNRPC_TRACE_TASK_SPECIFIER,
__entry->task_id, __entry->client_id)
);
TRACE_EVENT(rpcgss_bad_seqno,
......@@ -358,7 +361,8 @@ TRACE_EVENT(rpcgss_bad_seqno,
__entry->received = received;
),
TP_printk("task:%u@%u expected seqno %u, received seqno %u",
TP_printk(SUNRPC_TRACE_TASK_SPECIFIER
" expected seqno %u, received seqno %u",
__entry->task_id, __entry->client_id,
__entry->expected, __entry->received)
);
......@@ -386,7 +390,7 @@ TRACE_EVENT(rpcgss_seqno,
__entry->seqno = rqst->rq_seqno;
),
TP_printk("task:%u@%u xid=0x%08x seqno=%u",
TP_printk(SUNRPC_TRACE_TASK_SPECIFIER " xid=0x%08x seqno=%u",
__entry->task_id, __entry->client_id,
__entry->xid, __entry->seqno)
);
......@@ -418,7 +422,8 @@ TRACE_EVENT(rpcgss_need_reencode,
__entry->ret = ret;
),
TP_printk("task:%u@%u xid=0x%08x rq_seqno=%u seq_xmit=%u reencode %sneeded",
TP_printk(SUNRPC_TRACE_TASK_SPECIFIER
" xid=0x%08x rq_seqno=%u seq_xmit=%u reencode %sneeded",
__entry->task_id, __entry->client_id,
__entry->xid, __entry->seqno, __entry->seq_xmit,
__entry->ret ? "" : "un")
......@@ -452,7 +457,8 @@ TRACE_EVENT(rpcgss_update_slack,
__entry->verfsize = auth->au_verfsize;
),
TP_printk("task:%u@%u xid=0x%08x auth=%p rslack=%u ralign=%u verfsize=%u\n",
TP_printk(SUNRPC_TRACE_TASK_SPECIFIER
" xid=0x%08x auth=%p rslack=%u ralign=%u verfsize=%u\n",
__entry->task_id, __entry->client_id, __entry->xid,
__entry->auth, __entry->rslack, __entry->ralign,
__entry->verfsize)
......
This diff is collapsed.
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2021 Oracle and/or its affiliates.
*
* Common types and format specifiers for sunrpc.
*/
#if !defined(_TRACE_SUNRPC_BASE_H)
#define _TRACE_SUNRPC_BASE_H
#include <linux/tracepoint.h>
#define SUNRPC_TRACE_PID_SPECIFIER "%08x"
#define SUNRPC_TRACE_CLID_SPECIFIER "%08x"
#define SUNRPC_TRACE_TASK_SPECIFIER \
"task:" SUNRPC_TRACE_PID_SPECIFIER "@" SUNRPC_TRACE_CLID_SPECIFIER
#endif /* _TRACE_SUNRPC_BASE_H */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment