diff options
| author | Linus Torvalds <[email protected]> | 2021-11-10 16:32:46 -0800 | 
|---|---|---|
| committer | Linus Torvalds <[email protected]> | 2021-11-10 16:32:46 -0800 | 
| commit | 2ec20f489591962db8ff1718aa6055c08d88d0cc (patch) | |
| tree | 29d24324158dc13a2a37c48aed025997e7a9148e | |
| parent | 5147da902e0dd162c6254a61e4c57f21b60a9b1c (diff) | |
| parent | f96f8cc4a63dd645e07ea9712be4e0a76ea4ec1f (diff) | |
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()
  ...
59 files changed, 2011 insertions, 1814 deletions
| diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c index b11f2afa84f1..99fffc9cb958 100644 --- a/fs/lockd/clntproc.c +++ b/fs/lockd/clntproc.c @@ -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: diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c index e10ae2c41279..176b468a61c7 100644 --- a/fs/lockd/svc4proc.c +++ b/fs/lockd/svc4proc.c @@ -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) diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c index 99696d3f6dd6..4dc1b40a489a 100644 --- a/fs/lockd/svcproc.c +++ b/fs/lockd/svcproc.c @@ -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) diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c index ed9d580826f5..09c5b1cb3e07 100644 --- a/fs/nfs/callback_proc.c +++ b/fs/nfs/callback_proc.c @@ -739,6 +739,9 @@ out:  		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 */ diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 23e165d5ec9c..1e4dc1ab9312 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c @@ -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);  } diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index 11118398f495..7c9eb679dbdb 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c @@ -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;  } diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 1a6d2867fba4..731d31015b6a 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -78,6 +78,7 @@ static struct nfs_open_dir_context *alloc_nfs_open_dir_context(struct inode *dir  		ctx->attr_gencount = nfsi->attr_gencount;  		ctx->dir_cookie = 0;  		ctx->dup_cookie = 0; +		ctx->page_index = 0;  		spin_lock(&dir->i_lock);  		if (list_empty(&nfsi->open_files) &&  		    (nfsi->cache_validity & NFS_INO_DATA_INVAL_DEFER)) @@ -85,6 +86,7 @@ static struct nfs_open_dir_context *alloc_nfs_open_dir_context(struct inode *dir  					      NFS_INO_INVALID_DATA |  						      NFS_INO_REVAL_FORCED);  		list_add(&ctx->list, &nfsi->open_files); +		clear_bit(NFS_INO_FORCE_READDIR, &nfsi->flags);  		spin_unlock(&dir->i_lock);  		return ctx;  	} @@ -411,7 +413,8 @@ out_eof:  static bool  nfs_readdir_inode_mapping_valid(struct nfs_inode *nfsi)  { -	if (nfsi->cache_validity & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA)) +	if (nfsi->cache_validity & (NFS_INO_INVALID_CHANGE | +				    NFS_INO_INVALID_DATA))  		return false;  	smp_rmb();  	return !test_bit(NFS_INO_INVALIDATING, &nfsi->flags); @@ -626,8 +629,7 @@ void nfs_force_use_readdirplus(struct inode *dir)  	if (nfs_server_capable(dir, NFS_CAP_READDIRPLUS) &&  	    !list_empty(&nfsi->open_files)) {  		set_bit(NFS_INO_ADVISE_RDPLUS, &nfsi->flags); -		invalidate_mapping_pages(dir->i_mapping, -			nfsi->page_index + 1, -1); +		set_bit(NFS_INO_FORCE_READDIR, &nfsi->flags);  	}  } @@ -680,7 +682,7 @@ again:  			nfs_set_verifier(dentry, dir_verifier);  			status = nfs_refresh_inode(d_inode(dentry), entry->fattr);  			if (!status) -				nfs_setsecurity(d_inode(dentry), entry->fattr, entry->label); +				nfs_setsecurity(d_inode(dentry), entry->fattr);  			goto out;  		} else {  			d_invalidate(dentry); @@ -694,7 +696,7 @@ again:  		goto out;  	} -	inode = nfs_fhget(dentry->d_sb, entry->fh, entry->fattr, entry->label); +	inode = nfs_fhget(dentry->d_sb, entry->fh, entry->fattr);  	alias = d_splice_alias(inode, dentry);  	d_lookup_done(dentry);  	if (alias) { @@ -730,8 +732,8 @@ static int nfs_readdir_page_filler(struct nfs_readdir_descriptor *desc,  	xdr_set_scratch_page(&stream, scratch);  	do { -		if (entry->label) -			entry->label->len = NFS4_MAXLABELLEN; +		if (entry->fattr->label) +			entry->fattr->label->len = NFS4_MAXLABELLEN;  		status = xdr_decode(desc, entry, &stream);  		if (status != 0) @@ -836,21 +838,15 @@ static int nfs_readdir_xdr_to_array(struct nfs_readdir_descriptor *desc,  		return -ENOMEM;  	entry->cookie = nfs_readdir_page_last_cookie(page);  	entry->fh = nfs_alloc_fhandle(); -	entry->fattr = nfs_alloc_fattr(); +	entry->fattr = nfs_alloc_fattr_with_label(NFS_SERVER(inode));  	entry->server = NFS_SERVER(inode);  	if (entry->fh == NULL || entry->fattr == NULL)  		goto out; -	entry->label = nfs4_label_alloc(NFS_SERVER(inode), GFP_NOWAIT); -	if (IS_ERR(entry->label)) { -		status = PTR_ERR(entry->label); -		goto out; -	} -  	array_size = (dtsize + PAGE_SIZE - 1) >> PAGE_SHIFT;  	pages = nfs_readdir_alloc_pages(array_size);  	if (!pages) -		goto out_release_label; +		goto out;  	do {  		unsigned int pglen; @@ -873,8 +869,6 @@ static int nfs_readdir_xdr_to_array(struct nfs_readdir_descriptor *desc,  	} while (!status && nfs_readdir_page_needs_filling(page));  	nfs_readdir_free_pages(pages, array_size); -out_release_label: -	nfs4_label_free(entry->label);  out:  	nfs_free_fattr(entry->fattr);  	nfs_free_fhandle(entry->fh); @@ -937,10 +931,8 @@ static int find_and_lock_cache_page(struct nfs_readdir_descriptor *desc)  			       sizeof(nfsi->cookieverf));  	}  	res = nfs_readdir_search_array(desc); -	if (res == 0) { -		nfsi->page_index = desc->page_index; +	if (res == 0)  		return 0; -	}  	nfs_readdir_page_unlock_and_put_cached(desc);  	return res;  } @@ -1079,6 +1071,7 @@ static int nfs_readdir(struct file *file, struct dir_context *ctx)  	struct nfs_inode *nfsi = NFS_I(inode);  	struct nfs_open_dir_context *dir_ctx = file->private_data;  	struct nfs_readdir_descriptor *desc; +	pgoff_t page_index;  	int res;  	dfprintk(FILE, "NFS: readdir(%pD2) starting at cookie %llu\n", @@ -1109,10 +1102,15 @@ static int nfs_readdir(struct file *file, struct dir_context *ctx)  	desc->dir_cookie = dir_ctx->dir_cookie;  	desc->dup_cookie = dir_ctx->dup_cookie;  	desc->duped = dir_ctx->duped; +	page_index = dir_ctx->page_index;  	desc->attr_gencount = dir_ctx->attr_gencount;  	memcpy(desc->verf, dir_ctx->verf, sizeof(desc->verf));  	spin_unlock(&file->f_lock); +	if (test_and_clear_bit(NFS_INO_FORCE_READDIR, &nfsi->flags) && +	    list_is_singular(&nfsi->open_files)) +		invalidate_mapping_pages(inode->i_mapping, page_index + 1, -1); +  	do {  		res = readdir_search_pagecache(desc); @@ -1149,6 +1147,7 @@ static int nfs_readdir(struct file *file, struct dir_context *ctx)  	dir_ctx->dup_cookie = desc->dup_cookie;  	dir_ctx->duped = desc->duped;  	dir_ctx->attr_gencount = desc->attr_gencount; +	dir_ctx->page_index = desc->page_index;  	memcpy(dir_ctx->verf, desc->verf, sizeof(dir_ctx->verf));  	spin_unlock(&file->f_lock); @@ -1269,13 +1268,12 @@ static bool nfs_verifier_is_delegated(struct dentry *dentry)  static void nfs_set_verifier_locked(struct dentry *dentry, unsigned long verf)  {  	struct inode *inode = d_inode(dentry); +	struct inode *dir = d_inode(dentry->d_parent); -	if (!nfs_verifier_is_delegated(dentry) && -	    !nfs_verify_change_attribute(d_inode(dentry->d_parent), verf)) -		goto out; +	if (!nfs_verify_change_attribute(dir, verf)) +		return;  	if (inode && NFS_PROTO(inode)->have_delegation(inode, FMODE_READ))  		nfs_set_verifier_delegated(&verf); -out:  	dentry->d_time = verf;  } @@ -1413,7 +1411,7 @@ out_force:  static void nfs_mark_dir_for_revalidate(struct inode *inode)  {  	spin_lock(&inode->i_lock); -	nfs_set_cache_invalid(inode, NFS_INO_REVAL_PAGECACHE); +	nfs_set_cache_invalid(inode, NFS_INO_INVALID_CHANGE);  	spin_unlock(&inode->i_lock);  } @@ -1495,19 +1493,17 @@ nfs_lookup_revalidate_dentry(struct inode *dir, struct dentry *dentry,  {  	struct nfs_fh *fhandle;  	struct nfs_fattr *fattr; -	struct nfs4_label *label;  	unsigned long dir_verifier;  	int ret;  	ret = -ENOMEM;  	fhandle = nfs_alloc_fhandle(); -	fattr = nfs_alloc_fattr(); -	label = nfs4_label_alloc(NFS_SERVER(inode), GFP_KERNEL); -	if (fhandle == NULL || fattr == NULL || IS_ERR(label)) +	fattr = nfs_alloc_fattr_with_label(NFS_SERVER(inode)); +	if (fhandle == NULL || fattr == NULL)  		goto out;  	dir_verifier = nfs_save_change_attribute(dir); -	ret = NFS_PROTO(dir)->lookup(dir, dentry, fhandle, fattr, label); +	ret = NFS_PROTO(dir)->lookup(dir, dentry, fhandle, fattr);  	if (ret < 0) {  		switch (ret) {  		case -ESTALE: @@ -1526,7 +1522,7 @@ nfs_lookup_revalidate_dentry(struct inode *dir, struct dentry *dentry,  	if (nfs_refresh_inode(inode, fattr) < 0)  		goto out; -	nfs_setsecurity(inode, fattr, label); +	nfs_setsecurity(inode, fattr);  	nfs_set_verifier(dentry, dir_verifier);  	/* set a readdirplus hint that we had a cache miss */ @@ -1535,7 +1531,6 @@ nfs_lookup_revalidate_dentry(struct inode *dir, struct dentry *dentry,  out:  	nfs_free_fattr(fattr);  	nfs_free_fhandle(fhandle); -	nfs4_label_free(label);  	/*  	 * If the lookup failed despite the dentry change attribute being @@ -1721,10 +1716,6 @@ static void nfs_drop_nlink(struct inode *inode)   */  static void nfs_dentry_iput(struct dentry *dentry, struct inode *inode)  { -	if (S_ISDIR(inode->i_mode)) -		/* drop any readdir cache as it could easily be old */ -		nfs_set_cache_invalid(inode, NFS_INO_INVALID_DATA); -  	if (dentry->d_flags & DCACHE_NFSFS_RENAMED) {  		nfs_complete_unlink(dentry, inode);  		nfs_drop_nlink(inode); @@ -1759,7 +1750,6 @@ struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, unsigned in  	struct inode *inode = NULL;  	struct nfs_fh *fhandle = NULL;  	struct nfs_fattr *fattr = NULL; -	struct nfs4_label *label = NULL;  	unsigned long dir_verifier;  	int error; @@ -1778,27 +1768,23 @@ struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, unsigned in  	res = ERR_PTR(-ENOMEM);  	fhandle = nfs_alloc_fhandle(); -	fattr = nfs_alloc_fattr(); +	fattr = nfs_alloc_fattr_with_label(NFS_SERVER(dir));  	if (fhandle == NULL || fattr == NULL)  		goto out; -	label = nfs4_label_alloc(NFS_SERVER(dir), GFP_NOWAIT); -	if (IS_ERR(label)) -		goto out; -  	dir_verifier = nfs_save_change_attribute(dir);  	trace_nfs_lookup_enter(dir, dentry, flags); -	error = NFS_PROTO(dir)->lookup(dir, dentry, fhandle, fattr, label); +	error = NFS_PROTO(dir)->lookup(dir, dentry, fhandle, fattr);  	if (error == -ENOENT)  		goto no_entry;  	if (error < 0) {  		res = ERR_PTR(error); -		goto out_label; +		goto out;  	} -	inode = nfs_fhget(dentry->d_sb, fhandle, fattr, label); +	inode = nfs_fhget(dentry->d_sb, fhandle, fattr);  	res = ERR_CAST(inode);  	if (IS_ERR(res)) -		goto out_label; +		goto out;  	/* Notify readdir to use READDIRPLUS */  	nfs_force_use_readdirplus(dir); @@ -1807,14 +1793,12 @@ no_entry:  	res = d_splice_alias(inode, dentry);  	if (res != NULL) {  		if (IS_ERR(res)) -			goto out_label; +			goto out;  		dentry = res;  	}  	nfs_set_verifier(dentry, dir_verifier); -out_label: -	trace_nfs_lookup_exit(dir, dentry, flags, error); -	nfs4_label_free(label);  out: +	trace_nfs_lookup_exit(dir, dentry, flags, PTR_ERR_OR_ZERO(res));  	nfs_free_fattr(fattr);  	nfs_free_fhandle(fhandle);  	return res; @@ -2051,8 +2035,7 @@ static int nfs4_lookup_revalidate(struct dentry *dentry, unsigned int flags)  struct dentry *  nfs_add_or_obtain(struct dentry *dentry, struct nfs_fh *fhandle, -				struct nfs_fattr *fattr, -				struct nfs4_label *label) +				struct nfs_fattr *fattr)  {  	struct dentry *parent = dget_parent(dentry);  	struct inode *dir = d_inode(parent); @@ -2063,7 +2046,7 @@ nfs_add_or_obtain(struct dentry *dentry, struct nfs_fh *fhandle,  	d_drop(dentry);  	if (fhandle->size == 0) { -		error = NFS_PROTO(dir)->lookup(dir, dentry, fhandle, fattr, NULL); +		error = NFS_PROTO(dir)->lookup(dir, dentry, fhandle, fattr);  		if (error)  			goto out_error;  	} @@ -2071,11 +2054,11 @@ nfs_add_or_obtain(struct dentry *dentry, struct nfs_fh *fhandle,  	if (!(fattr->valid & NFS_ATTR_FATTR)) {  		struct nfs_server *server = NFS_SB(dentry->d_sb);  		error = server->nfs_client->rpc_ops->getattr(server, fhandle, -				fattr, NULL, NULL); +				fattr, NULL);  		if (error < 0)  			goto out_error;  	} -	inode = nfs_fhget(dentry->d_sb, fhandle, fattr, label); +	inode = nfs_fhget(dentry->d_sb, fhandle, fattr);  	d = d_splice_alias(inode, dentry);  out:  	dput(parent); @@ -2090,12 +2073,11 @@ 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 nfs_fattr *fattr)  {  	struct dentry *d; -	d = nfs_add_or_obtain(dentry, fhandle, fattr, label); +	d = nfs_add_or_obtain(dentry, fhandle, fattr);  	if (IS_ERR(d))  		return PTR_ERR(d); @@ -2197,6 +2179,18 @@ static void nfs_dentry_handle_enoent(struct dentry *dentry)  		d_delete(dentry);  } +static void nfs_dentry_remove_handle_error(struct inode *dir, +					   struct dentry *dentry, int error) +{ +	switch (error) { +	case -ENOENT: +		d_delete(dentry); +		fallthrough; +	case 0: +		nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); +	} +} +  int nfs_rmdir(struct inode *dir, struct dentry *dentry)  {  	int error; @@ -2219,6 +2213,7 @@ int nfs_rmdir(struct inode *dir, struct dentry *dentry)  		up_write(&NFS_I(d_inode(dentry))->rmdir_sem);  	} else  		error = NFS_PROTO(dir)->rmdir(dir, &dentry->d_name); +	nfs_dentry_remove_handle_error(dir, dentry, error);  	trace_nfs_rmdir_exit(dir, dentry, error);  	return error; @@ -2288,9 +2283,8 @@ int nfs_unlink(struct inode *dir, struct dentry *dentry)  	}  	spin_unlock(&dentry->d_lock);  	error = nfs_safe_remove(dentry); -	if (!error || error == -ENOENT) { -		nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); -	} else if (need_rehash) +	nfs_dentry_remove_handle_error(dir, dentry, error); +	if (need_rehash)  		d_rehash(dentry);  out:  	trace_nfs_unlink_exit(dir, dentry, error); @@ -2352,6 +2346,8 @@ int nfs_symlink(struct user_namespace *mnt_userns, struct inode *dir,  		return error;  	} +	nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); +  	/*  	 * No big deal if we can't add this page to the page cache here.  	 * READLINK will get the missing page from the server if needed. @@ -2385,6 +2381,7 @@ nfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)  	d_drop(dentry);  	error = NFS_PROTO(dir)->link(inode, dir, &dentry->d_name);  	if (error == 0) { +		nfs_set_verifier(dentry, nfs_save_change_attribute(dir));  		ihold(inode);  		d_add(dentry, inode);  	} diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 7a5f287c5391..9cff8709c80a 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c @@ -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);  } diff --git a/fs/nfs/export.c b/fs/nfs/export.c index d772c20bbfd1..171c424cb6d5 100644 --- a/fs/nfs/export.c +++ b/fs/nfs/export.c @@ -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;  } diff --git a/fs/nfs/filelayout/filelayout.c b/fs/nfs/filelayout/filelayout.c index d2103852475f..9c96e3e5ed35 100644 --- a/fs/nfs/filelayout/filelayout.c +++ b/fs/nfs/filelayout/filelayout.c @@ -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); diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c index d383de00d486..a553d59afa8b 100644 --- a/fs/nfs/flexfilelayout/flexfilelayout.c +++ b/fs/nfs/flexfilelayout/flexfilelayout.c @@ -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); diff --git a/fs/nfs/flexfilelayout/flexfilelayoutdev.c b/fs/nfs/flexfilelayout/flexfilelayoutdev.c index c9b61b818ec1..bfa7202ca7be 100644 --- a/fs/nfs/flexfilelayout/flexfilelayoutdev.c +++ b/fs/nfs/flexfilelayout/flexfilelayoutdev.c @@ -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. diff --git a/fs/nfs/getroot.c b/fs/nfs/getroot.c index 59355c106ece..11ff2b2e060f 100644 --- a/fs/nfs/getroot.c +++ b/fs/nfs/getroot.c @@ -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 @@ out:  error_splat_root:  	dput(fc->root);  	fc->root = NULL; -	goto out_label; +	goto out_fattr;  } diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 853213b3a209..dd53704c3f40 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -210,10 +210,15 @@ void nfs_set_cache_invalid(struct inode *inode, unsigned long flags)  		flags &= ~NFS_INO_INVALID_XATTR;  	if (flags & NFS_INO_INVALID_DATA)  		nfs_fscache_invalidate(inode); -	if (inode->i_mapping->nrpages == 0) -		flags &= ~(NFS_INO_INVALID_DATA|NFS_INO_DATA_INVAL_DEFER);  	flags &= ~(NFS_INO_REVAL_PAGECACHE | NFS_INO_REVAL_FORCED); +  	nfsi->cache_validity |= flags; + +	if (inode->i_mapping->nrpages == 0) +		nfsi->cache_validity &= ~(NFS_INO_INVALID_DATA | +					  NFS_INO_DATA_INVAL_DEFER); +	else if (nfsi->cache_validity & NFS_INO_INVALID_DATA) +		nfsi->cache_validity &= ~NFS_INO_DATA_INVAL_DEFER;  }  EXPORT_SYMBOL_GPL(nfs_set_cache_invalid); @@ -350,37 +355,32 @@ static void nfs_clear_label_invalid(struct inode *inode)  	spin_unlock(&inode->i_lock);  } -void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr, -					struct nfs4_label *label) +void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr)  {  	int error; -	if (label == NULL) +	if (fattr->label == NULL)  		return;  	if ((fattr->valid & NFS_ATTR_FATTR_V4_SECURITY_LABEL) && inode->i_security) { -		error = security_inode_notifysecctx(inode, label->label, -				label->len); +		error = security_inode_notifysecctx(inode, fattr->label->label, +				fattr->label->len);  		if (error)  			printk(KERN_ERR "%s() %s %d "  					"security_inode_notifysecctx() %d\n",  					__func__, -					(char *)label->label, -					label->len, error); +					(char *)fattr->label->label, +					fattr->label->len, error);  		nfs_clear_label_invalid(inode);  	}  }  struct nfs4_label *nfs4_label_alloc(struct nfs_server *server, gfp_t flags)  { -	struct nfs4_label *label = NULL; -	int minor_version = server->nfs_client->cl_minorversion; - -	if (minor_version < 2) -		return label; +	struct nfs4_label *label;  	if (!(server->caps & NFS_CAP_SECURITY_LABEL)) -		return label; +		return NULL;  	label = kzalloc(sizeof(struct nfs4_label), flags);  	if (label == NULL) @@ -397,8 +397,7 @@ struct nfs4_label *nfs4_label_alloc(struct nfs_server *server, gfp_t flags)  }  EXPORT_SYMBOL_GPL(nfs4_label_alloc);  #else -void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr, -					struct nfs4_label *label) +void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr)  {  }  #endif @@ -426,12 +425,28 @@ nfs_ilookup(struct super_block *sb, struct nfs_fattr *fattr, struct nfs_fh *fh)  	return inode;  } +static void nfs_inode_init_regular(struct nfs_inode *nfsi) +{ +	atomic_long_set(&nfsi->nrequests, 0); +	INIT_LIST_HEAD(&nfsi->commit_info.list); +	atomic_long_set(&nfsi->commit_info.ncommit, 0); +	atomic_set(&nfsi->commit_info.rpcs_out, 0); +	mutex_init(&nfsi->commit_mutex); +} + +static void nfs_inode_init_dir(struct nfs_inode *nfsi) +{ +	nfsi->cache_change_attribute = 0; +	memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf)); +	init_rwsem(&nfsi->rmdir_sem); +} +  /*   * This is our front-end to iget that looks up inodes by file handle   * instead of inode number.   */  struct inode * -nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, struct nfs4_label *label) +nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)  {  	struct nfs_find_desc desc = {  		.fh	= fh, @@ -480,10 +495,12 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st  		if (S_ISREG(inode->i_mode)) {  			inode->i_fop = NFS_SB(sb)->nfs_client->rpc_ops->file_ops;  			inode->i_data.a_ops = &nfs_file_aops; +			nfs_inode_init_regular(nfsi);  		} else if (S_ISDIR(inode->i_mode)) {  			inode->i_op = NFS_SB(sb)->nfs_client->rpc_ops->dir_inode_ops;  			inode->i_fop = &nfs_dir_operations;  			inode->i_data.a_ops = &nfs_dir_aops; +			nfs_inode_init_dir(nfsi);  			/* Deal with crossing mountpoints */  			if (fattr->valid & NFS_ATTR_FATTR_MOUNTPOINT ||  					fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL) { @@ -509,7 +526,6 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st  		inode->i_uid = make_kuid(&init_user_ns, -2);  		inode->i_gid = make_kgid(&init_user_ns, -2);  		inode->i_blocks = 0; -		memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf));  		nfsi->write_io = 0;  		nfsi->read_io = 0; @@ -563,7 +579,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st  			   fattr->size != 0)  			nfs_set_cache_invalid(inode, NFS_INO_INVALID_BLOCKS); -		nfs_setsecurity(inode, fattr, label); +		nfs_setsecurity(inode, fattr);  		nfsi->attrtimeo = NFS_MINATTRTIMEO(inode);  		nfsi->attrtimeo_timestamp = now; @@ -632,7 +648,7 @@ nfs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,  	if (S_ISREG(inode->i_mode))  		nfs_sync_inode(inode); -	fattr = nfs_alloc_fattr(); +	fattr = nfs_alloc_fattr_with_label(NFS_SERVER(inode));  	if (fattr == NULL) {  		error = -ENOMEM;  		goto out; @@ -666,6 +682,7 @@ static int nfs_vmtruncate(struct inode * inode, loff_t offset)  	if (err)  		goto out; +	trace_nfs_size_truncate(inode, offset);  	i_size_write(inode, offset);  	/* Optimisation */  	if (offset == 0) @@ -1024,7 +1041,7 @@ struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry,  		ctx->cred = get_cred(filp->f_cred);  	else  		ctx->cred = get_current_cred(); -	ctx->ll_cred = NULL; +	rcu_assign_pointer(ctx->ll_cred, NULL);  	ctx->state = NULL;  	ctx->mode = f_mode;  	ctx->flags = 0; @@ -1063,7 +1080,7 @@ static void __put_nfs_open_context(struct nfs_open_context *ctx, int is_sync)  	put_cred(ctx->cred);  	dput(ctx->dentry);  	nfs_sb_deactive(sb); -	put_rpccred(ctx->ll_cred); +	put_rpccred(rcu_dereference_protected(ctx->ll_cred, 1));  	kfree(ctx->mdsthreshold);  	kfree_rcu(ctx, rcu_head);  } @@ -1175,7 +1192,6 @@ int  __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)  {  	int		 status = -ESTALE; -	struct nfs4_label *label = NULL;  	struct nfs_fattr *fattr = NULL;  	struct nfs_inode *nfsi = NFS_I(inode); @@ -1197,20 +1213,13 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)  	}  	status = -ENOMEM; -	fattr = nfs_alloc_fattr(); +	fattr = nfs_alloc_fattr_with_label(NFS_SERVER(inode));  	if (fattr == NULL)  		goto out;  	nfs_inc_stats(inode, NFSIOS_INODEREVALIDATE); -	label = nfs4_label_alloc(NFS_SERVER(inode), GFP_KERNEL); -	if (IS_ERR(label)) { -		status = PTR_ERR(label); -		goto out; -	} - -	status = NFS_PROTO(inode)->getattr(server, NFS_FH(inode), fattr, -			label, inode); +	status = NFS_PROTO(inode)->getattr(server, NFS_FH(inode), fattr, inode);  	if (status != 0) {  		dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Lu) getattr failed, error=%d\n",  			 inode->i_sb->s_id, @@ -1227,7 +1236,7 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)  			else  				nfs_zap_caches(inode);  		} -		goto err_out; +		goto out;  	}  	status = nfs_refresh_inode(inode, fattr); @@ -1235,20 +1244,18 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)  		dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Lu) refresh failed, error=%d\n",  			 inode->i_sb->s_id,  			 (unsigned long long)NFS_FILEID(inode), status); -		goto err_out; +		goto out;  	}  	if (nfsi->cache_validity & NFS_INO_INVALID_ACL)  		nfs_zap_acl_cache(inode); -	nfs_setsecurity(inode, fattr, label); +	nfs_setsecurity(inode, fattr);  	dfprintk(PAGECACHE, "NFS: (%s/%Lu) revalidation complete\n",  		inode->i_sb->s_id,  		(unsigned long long)NFS_FILEID(inode)); -err_out: -	nfs4_label_free(label);  out:  	nfs_free_fattr(fattr);  	trace_nfs_revalidate_inode_exit(inode, status); @@ -1446,13 +1453,12 @@ static void nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr *fattr)  			&& (fattr->valid & NFS_ATTR_FATTR_MTIME)  			&& timespec64_equal(&ts, &fattr->pre_mtime)) {  		inode->i_mtime = fattr->mtime; -		if (S_ISDIR(inode->i_mode)) -			nfs_set_cache_invalid(inode, NFS_INO_INVALID_DATA);  	}  	if ((fattr->valid & NFS_ATTR_FATTR_PRESIZE)  			&& (fattr->valid & NFS_ATTR_FATTR_SIZE)  			&& i_size_read(inode) == nfs_size_to_loff_t(fattr->pre_size)  			&& !nfs_have_writebacks(inode)) { +		trace_nfs_size_wcc(inode, fattr->size);  		i_size_write(inode, nfs_size_to_loff_t(fattr->size));  	}  } @@ -1580,12 +1586,31 @@ struct nfs_fattr *nfs_alloc_fattr(void)  	struct nfs_fattr *fattr;  	fattr = kmalloc(sizeof(*fattr), GFP_NOFS); -	if (fattr != NULL) +	if (fattr != NULL) {  		nfs_fattr_init(fattr); +		fattr->label = NULL; +	}  	return fattr;  }  EXPORT_SYMBOL_GPL(nfs_alloc_fattr); +struct nfs_fattr *nfs_alloc_fattr_with_label(struct nfs_server *server) +{ +	struct nfs_fattr *fattr = nfs_alloc_fattr(); + +	if (!fattr) +		return NULL; + +	fattr->label = nfs4_label_alloc(server, GFP_NOFS); +	if (IS_ERR(fattr->label)) { +		kfree(fattr); +		return NULL; +	} + +	return fattr; +} +EXPORT_SYMBOL_GPL(nfs_alloc_fattr_with_label); +  struct nfs_fh *nfs_alloc_fhandle(void)  {  	struct nfs_fh *fh; @@ -1777,8 +1802,10 @@ static int nfs_inode_finish_partial_attr_update(const struct nfs_fattr *fattr,  		NFS_INO_INVALID_BLOCKS | NFS_INO_INVALID_OTHER |  		NFS_INO_INVALID_NLINK;  	unsigned long cache_validity = NFS_I(inode)->cache_validity; +	enum nfs4_change_attr_type ctype = NFS_SERVER(inode)->change_attr_type; -	if (!(cache_validity & NFS_INO_INVALID_CHANGE) && +	if (ctype != NFS4_CHANGE_TYPE_IS_UNDEFINED && +	    !(cache_validity & NFS_INO_INVALID_CHANGE) &&  	    (cache_validity & check_valid) != 0 &&  	    (fattr->valid & NFS_ATTR_FATTR_CHANGE) != 0 &&  	    nfs_inode_attrs_cmp_monotonic(fattr, inode) == 0) @@ -2095,16 +2122,11 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)  			/* Do we perhaps have any outstanding writes, or has  			 * the file grown beyond our last write? */  			if (!nfs_have_writebacks(inode) || new_isize > cur_isize) { +				trace_nfs_size_update(inode, new_isize);  				i_size_write(inode, new_isize);  				if (!have_writers)  					invalid |= NFS_INO_INVALID_DATA;  			} -			dprintk("NFS: isize change on server for file %s/%ld " -					"(%Ld to %Ld)\n", -					inode->i_sb->s_id, -					inode->i_ino, -					(long long)cur_isize, -					(long long)new_isize);  		}  		if (new_isize == 0 &&  		    !(fattr->valid & (NFS_ATTR_FATTR_SPACE_USED | @@ -2155,11 +2177,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)  			save_cache_validity & NFS_INO_INVALID_OTHER;  	if (fattr->valid & NFS_ATTR_FATTR_NLINK) { -		if (inode->i_nlink != fattr->nlink) { -			if (S_ISDIR(inode->i_mode)) -				invalid |= NFS_INO_INVALID_DATA; +		if (inode->i_nlink != fattr->nlink)  			set_nlink(inode, fattr->nlink); -		}  	} else if (fattr_supported & NFS_ATTR_FATTR_NLINK)  		nfsi->cache_validity |=  			save_cache_validity & NFS_INO_INVALID_NLINK; @@ -2260,14 +2279,7 @@ static void init_once(void *foo)  	INIT_LIST_HEAD(&nfsi->open_files);  	INIT_LIST_HEAD(&nfsi->access_cache_entry_lru);  	INIT_LIST_HEAD(&nfsi->access_cache_inode_lru); -	INIT_LIST_HEAD(&nfsi->commit_info.list); -	atomic_long_set(&nfsi->nrequests, 0); -	atomic_long_set(&nfsi->commit_info.ncommit, 0); -	atomic_set(&nfsi->commit_info.rpcs_out, 0); -	init_rwsem(&nfsi->rmdir_sem); -	mutex_init(&nfsi->commit_mutex);  	nfs4_init_once(nfsi); -	nfsi->cache_change_attribute = 0;  }  static int __init nfs_init_inodecache(void) diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 66fc936834f2..12f6acb483bb 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -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)  {  } diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c index bc0c698f3350..3295af4110f1 100644 --- a/fs/nfs/namespace.c +++ b/fs/nfs/namespace.c @@ -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; diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index f7524310ddf4..7100514d306b 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c @@ -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) diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c index e6eca1d7481b..9274c9c5efea 100644 --- a/fs/nfs/nfs3xdr.c +++ b/fs/nfs/nfs3xdr.c @@ -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;  } diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c index a24349512ffe..08355b66e7cb 100644 --- a/fs/nfs/nfs42proc.c +++ b/fs/nfs/nfs42proc.c @@ -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); diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index ba78df4b13d9..ed5eaca6801e 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h @@ -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, diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c index af57332503be..d8b5a250ca05 100644 --- a/fs/nfs/nfs4client.c +++ b/fs/nfs/nfs4client.c @@ -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 @@ error:  	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)));  } diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c index c91565227ea2..e79ae4cbc395 100644 --- a/fs/nfs/nfs4file.c +++ b/fs/nfs/nfs4file.c @@ -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); diff --git a/fs/nfs/nfs4idmap.c b/fs/nfs/nfs4idmap.c index 8d8aba305ecc..f331866dd418 100644 --- a/fs/nfs/nfs4idmap.c +++ b/fs/nfs/nfs4idmap.c @@ -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;  } diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 459860aa8fd7..ee3bc79f6ca3 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -93,11 +93,11 @@ struct nfs4_opendata;  static int _nfs4_recover_proc_open(struct nfs4_opendata *data);  static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *);  static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr); -static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr, struct nfs4_label *label, struct inode *inode); +static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, +			      struct nfs_fattr *fattr, struct inode *inode);  static int nfs4_do_setattr(struct inode *inode, const struct cred *cred,  			    struct nfs_fattr *fattr, struct iattr *sattr, -			    struct nfs_open_context *ctx, struct nfs4_label *ilabel, -			    struct nfs4_label *olabel); +			    struct nfs_open_context *ctx, struct nfs4_label *ilabel);  #ifdef CONFIG_NFS_V4_1  static struct rpc_task *_nfs41_proc_sequence(struct nfs_client *clp,  		const struct cred *cred, @@ -1330,7 +1330,6 @@ nfs4_map_atomic_open_claim(struct nfs_server *server,  static void nfs4_init_opendata_res(struct nfs4_opendata *p)  {  	p->o_res.f_attr = &p->f_attr; -	p->o_res.f_label = p->f_label;  	p->o_res.seqid = p->o_arg.seqid;  	p->c_res.seqid = p->c_arg.seqid;  	p->o_res.server = p->o_arg.server; @@ -1356,8 +1355,8 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,  	if (p == NULL)  		goto err; -	p->f_label = nfs4_label_alloc(server, gfp_mask); -	if (IS_ERR(p->f_label)) +	p->f_attr.label = nfs4_label_alloc(server, gfp_mask); +	if (IS_ERR(p->f_attr.label))  		goto err_free_p;  	p->a_label = nfs4_label_alloc(server, gfp_mask); @@ -1389,27 +1388,22 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,  					sizeof(p->o_arg.u.verifier.data));  		}  	} -	/* don't put an ACCESS op in OPEN compound if O_EXCL, because ACCESS -	 * will return permission denied for all bits until close */ -	if (!(flags & O_EXCL)) { -		/* ask server to check for all possible rights as results -		 * are cached */ -		switch (p->o_arg.claim) { -		default: -			break; -		case NFS4_OPEN_CLAIM_NULL: -		case NFS4_OPEN_CLAIM_FH: -			p->o_arg.access = NFS4_ACCESS_READ | -				NFS4_ACCESS_MODIFY | -				NFS4_ACCESS_EXTEND | -				NFS4_ACCESS_EXECUTE; +	/* ask server to check for all possible rights as results +	 * are cached */ +	switch (p->o_arg.claim) { +	default: +		break; +	case NFS4_OPEN_CLAIM_NULL: +	case NFS4_OPEN_CLAIM_FH: +		p->o_arg.access = NFS4_ACCESS_READ | NFS4_ACCESS_MODIFY | +				  NFS4_ACCESS_EXTEND | NFS4_ACCESS_DELETE | +				  NFS4_ACCESS_EXECUTE;  #ifdef CONFIG_NFS_V4_2 -			if (server->caps & NFS_CAP_XATTR) -				p->o_arg.access |= NFS4_ACCESS_XAREAD | -				    NFS4_ACCESS_XAWRITE | -				    NFS4_ACCESS_XALIST; +		if (!(server->caps & NFS_CAP_XATTR)) +			break; +		p->o_arg.access |= NFS4_ACCESS_XAREAD | NFS4_ACCESS_XAWRITE | +				   NFS4_ACCESS_XALIST;  #endif -		}  	}  	p->o_arg.clientid = server->nfs_client->cl_clientid;  	p->o_arg.id.create_time = ktime_to_ns(sp->so_seqid.create_time); @@ -1440,7 +1434,7 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,  err_free_label:  	nfs4_label_free(p->a_label);  err_free_f: -	nfs4_label_free(p->f_label); +	nfs4_label_free(p->f_attr.label);  err_free_p:  	kfree(p);  err: @@ -1462,7 +1456,7 @@ static void nfs4_opendata_free(struct kref *kref)  	nfs4_put_state_owner(p->owner);  	nfs4_label_free(p->a_label); -	nfs4_label_free(p->f_label); +	nfs4_label_free(p->f_attr.label);  	dput(p->dir);  	dput(p->dentry); @@ -1610,15 +1604,16 @@ static bool nfs_stateid_is_sequential(struct nfs4_state *state,  {  	if (test_bit(NFS_OPEN_STATE, &state->flags)) {  		/* The common case - we're updating to a new sequence number */ -		if (nfs4_stateid_match_other(stateid, &state->open_stateid) && -			nfs4_stateid_is_next(&state->open_stateid, stateid)) { -			return true; +		if (nfs4_stateid_match_other(stateid, &state->open_stateid)) { +			if (nfs4_stateid_is_next(&state->open_stateid, stateid)) +				return true; +			return false;  		} -	} else { -		/* This is the first OPEN in this generation */ -		if (stateid->seqid == cpu_to_be32(1)) -			return true; +		/* The server returned a new stateid */  	} +	/* This is the first OPEN in this generation */ +	if (stateid->seqid == cpu_to_be32(1)) +		return true;  	return false;  } @@ -2014,7 +2009,7 @@ nfs4_opendata_get_inode(struct nfs4_opendata *data)  		if (!(data->f_attr.valid & NFS_ATTR_FATTR))  			return ERR_PTR(-EAGAIN);  		inode = nfs_fhget(data->dir->d_sb, &data->o_res.fh, -				&data->f_attr, data->f_label); +				&data->f_attr);  		break;  	default:  		inode = d_inode(data->dentry); @@ -2473,11 +2468,15 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata)  	/* Set the create mode (note dependency on the session type) */  	data->o_arg.createmode = NFS4_CREATE_UNCHECKED;  	if (data->o_arg.open_flags & O_EXCL) { -		data->o_arg.createmode = NFS4_CREATE_EXCLUSIVE; -		if (nfs4_has_persistent_session(clp)) +		data->o_arg.createmode = NFS4_CREATE_EXCLUSIVE4_1; +		if (clp->cl_mvops->minor_version == 0) { +			data->o_arg.createmode = NFS4_CREATE_EXCLUSIVE; +			/* don't put an ACCESS op in OPEN compound if O_EXCL, +			 * because ACCESS will return permission denied for +			 * all bits until close */ +			data->o_res.access_request = data->o_arg.access = 0; +		} else if (nfs4_has_persistent_session(clp))  			data->o_arg.createmode = NFS4_CREATE_GUARDED; -		else if (clp->cl_mvops->minor_version > 0) -			data->o_arg.createmode = NFS4_CREATE_EXCLUSIVE4_1;  	}  	return;  unlock_no_action: @@ -2709,8 +2708,7 @@ static int _nfs4_proc_open(struct nfs4_opendata *data,  	}  	if (!(o_res->f_attr->valid & NFS_ATTR_FATTR)) {  		nfs4_sequence_free_slot(&o_res->seq_res); -		nfs4_proc_getattr(server, &o_res->fh, o_res->f_attr, -				o_res->f_label, NULL); +		nfs4_proc_getattr(server, &o_res->fh, o_res->f_attr, NULL);  	}  	return 0;  } @@ -3126,7 +3124,6 @@ static int _nfs4_do_open(struct inode *dir,  	enum open_claim_type4 claim = NFS4_OPEN_CLAIM_NULL;  	struct iattr *sattr = c->sattr;  	struct nfs4_label *label = c->label; -	struct nfs4_label *olabel = NULL;  	int status;  	/* Protect against reboot recovery conflicts */ @@ -3149,19 +3146,11 @@ static int _nfs4_do_open(struct inode *dir,  	if (opendata == NULL)  		goto err_put_state_owner; -	if (label) { -		olabel = nfs4_label_alloc(server, GFP_KERNEL); -		if (IS_ERR(olabel)) { -			status = PTR_ERR(olabel); -			goto err_opendata_put; -		} -	} -  	if (server->attr_bitmask[2] & FATTR4_WORD2_MDSTHRESHOLD) {  		if (!opendata->f_attr.mdsthreshold) {  			opendata->f_attr.mdsthreshold = pnfs_mdsthreshold_alloc();  			if (!opendata->f_attr.mdsthreshold) -				goto err_free_label; +				goto err_opendata_put;  		}  		opendata->o_arg.open_bitmap = &nfs4_pnfs_open_bitmap[0];  	} @@ -3170,7 +3159,7 @@ static int _nfs4_do_open(struct inode *dir,  	status = _nfs4_open_and_get_state(opendata, flags, ctx);  	if (status != 0) -		goto err_free_label; +		goto err_opendata_put;  	state = ctx->state;  	if ((opendata->o_arg.open_flags & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL) && @@ -3187,11 +3176,11 @@ static int _nfs4_do_open(struct inode *dir,  			nfs_fattr_init(opendata->o_res.f_attr);  			status = nfs4_do_setattr(state->inode, cred,  					opendata->o_res.f_attr, sattr, -					ctx, label, olabel); +					ctx, label);  			if (status == 0) {  				nfs_setattr_update_inode(state->inode, sattr,  						opendata->o_res.f_attr); -				nfs_setsecurity(state->inode, opendata->o_res.f_attr, olabel); +				nfs_setsecurity(state->inode, opendata->o_res.f_attr);  			}  			sattr->ia_valid = ia_old;  		} @@ -3204,13 +3193,9 @@ static int _nfs4_do_open(struct inode *dir,  		opendata->f_attr.mdsthreshold = NULL;  	} -	nfs4_label_free(olabel); -  	nfs4_opendata_put(opendata);  	nfs4_put_state_owner(sp);  	return 0; -err_free_label: -	nfs4_label_free(olabel);  err_opendata_put:  	nfs4_opendata_put(opendata);  err_put_state_owner: @@ -3355,8 +3340,7 @@ zero_stateid:  static int nfs4_do_setattr(struct inode *inode, const struct cred *cred,  			   struct nfs_fattr *fattr, struct iattr *sattr, -			   struct nfs_open_context *ctx, struct nfs4_label *ilabel, -			   struct nfs4_label *olabel) +			   struct nfs_open_context *ctx, struct nfs4_label *ilabel)  {  	struct nfs_server *server = NFS_SERVER(inode);  	__u32 bitmask[NFS4_BITMASK_SZ]; @@ -3370,7 +3354,6 @@ static int nfs4_do_setattr(struct inode *inode, const struct cred *cred,  	};  	struct nfs_setattrres  res = {  		.fattr		= fattr, -		.label		= olabel,  		.server		= server,  	};  	struct nfs4_exception exception = { @@ -3387,7 +3370,7 @@ static int nfs4_do_setattr(struct inode *inode, const struct cred *cred,  		adjust_flags |= NFS_INO_INVALID_OTHER;  	do { -		nfs4_bitmap_copy_adjust(bitmask, nfs4_bitmask(server, olabel), +		nfs4_bitmap_copy_adjust(bitmask, nfs4_bitmask(server, fattr->label),  					inode, adjust_flags);  		err = _nfs4_do_setattr(inode, &arg, &res, cred, ctx); @@ -3562,7 +3545,6 @@ static void nfs4_close_done(struct rpc_task *task, void *data)  		.stateid = &calldata->arg.stateid,  	}; -	dprintk("%s: begin!\n", __func__);  	if (!nfs4_sequence_done(task, &calldata->res.seq_res))  		return;  	trace_nfs4_close(state, &calldata->arg, &calldata->res, task->tk_status); @@ -3617,7 +3599,7 @@ out_release:  	task->tk_status = 0;  	nfs_release_seqid(calldata->arg.seqid);  	nfs_refresh_inode(calldata->inode, &calldata->fattr); -	dprintk("%s: done, ret = %d!\n", __func__, task->tk_status); +	dprintk("%s: ret = %d\n", __func__, task->tk_status);  	return;  out_restart:  	task->tk_status = 0; @@ -3635,7 +3617,6 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)  	bool is_rdonly, is_wronly, is_rdwr;  	int call_close = 0; -	dprintk("%s: begin!\n", __func__);  	if (nfs_wait_on_sequence(calldata->arg.seqid, task) != 0)  		goto out_wait; @@ -3709,7 +3690,6 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)  				&calldata->res.seq_res,  				task) != 0)  		nfs_release_seqid(calldata->arg.seqid); -	dprintk("%s: done!\n", __func__);  	return;  out_no_action:  	task->tk_action = NULL; @@ -3942,6 +3922,8 @@ int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)  		.interruptible = true,  	};  	int err; + +	nfs4_server_set_init_caps(server);  	do {  		err = nfs4_handle_exception(server,  				_nfs4_server_capabilities(server, fhandle), @@ -4105,7 +4087,6 @@ static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *mntfh,  {  	int error;  	struct nfs_fattr *fattr = info->fattr; -	struct nfs4_label *label = fattr->label;  	error = nfs4_server_capabilities(server, mntfh);  	if (error < 0) { @@ -4113,7 +4094,7 @@ static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *mntfh,  		return error;  	} -	error = nfs4_proc_getattr(server, mntfh, fattr, label, NULL); +	error = nfs4_proc_getattr(server, mntfh, fattr, NULL);  	if (error < 0) {  		dprintk("nfs4_get_root: getattr error = %d\n", -error);  		goto out; @@ -4176,8 +4157,7 @@ out:  }  static 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)  {  	__u32 bitmask[NFS4_BITMASK_SZ];  	struct nfs4_getattr_arg args = { @@ -4186,7 +4166,6 @@ static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,  	};  	struct nfs4_getattr_res res = {  		.fattr = fattr, -		.label = label,  		.server = server,  	};  	struct rpc_message msg = { @@ -4203,7 +4182,7 @@ static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,  	if (inode && (server->flags & NFS_MOUNT_SOFTREVAL))  		task_flags |= RPC_TASK_TIMEOUT; -	nfs4_bitmap_copy_adjust(bitmask, nfs4_bitmask(server, label), inode, 0); +	nfs4_bitmap_copy_adjust(bitmask, nfs4_bitmask(server, fattr->label), inode, 0);  	nfs_fattr_init(fattr);  	nfs4_init_sequence(&args.seq_args, &res.seq_res, 0, 0);  	return nfs4_do_call_sync(server->client, server, &msg, @@ -4211,15 +4190,14 @@ static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,  }  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)  {  	struct nfs4_exception exception = {  		.interruptible = true,  	};  	int err;  	do { -		err = _nfs4_proc_getattr(server, fhandle, fattr, label, inode); +		err = _nfs4_proc_getattr(server, fhandle, fattr, inode);  		trace_nfs4_getattr(server, fhandle, fattr, err);  		err = nfs4_handle_exception(server, err,  				&exception); @@ -4251,7 +4229,6 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,  	struct inode *inode = d_inode(dentry);  	const struct cred *cred = NULL;  	struct nfs_open_context *ctx = NULL; -	struct nfs4_label *label = NULL;  	int status;  	if (pnfs_ld_layoutret_on_setattr(inode) && @@ -4277,26 +4254,21 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,  			cred = ctx->cred;  	} -	label = nfs4_label_alloc(NFS_SERVER(inode), GFP_KERNEL); -	if (IS_ERR(label)) -		return PTR_ERR(label); -  	/* Return any delegations if we're going to change ACLs */  	if ((sattr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID)) != 0)  		nfs4_inode_make_writeable(inode); -	status = nfs4_do_setattr(inode, cred, fattr, sattr, ctx, NULL, label); +	status = nfs4_do_setattr(inode, cred, fattr, sattr, ctx, NULL);  	if (status == 0) {  		nfs_setattr_update_inode(inode, sattr, fattr); -		nfs_setsecurity(inode, fattr, label); +		nfs_setsecurity(inode, fattr);  	} -	nfs4_label_free(label);  	return status;  }  static int _nfs4_proc_lookup(struct rpc_clnt *clnt, struct inode *dir,  		struct dentry *dentry, struct nfs_fh *fhandle, -		struct nfs_fattr *fattr, struct nfs4_label *label) +		struct nfs_fattr *fattr)  {  	struct nfs_server *server = NFS_SERVER(dir);  	int		       status; @@ -4308,7 +4280,6 @@ static int _nfs4_proc_lookup(struct rpc_clnt *clnt, struct inode *dir,  	struct nfs4_lookup_res res = {  		.server = server,  		.fattr = fattr, -		.label = label,  		.fh = fhandle,  	};  	struct rpc_message msg = { @@ -4325,7 +4296,7 @@ static int _nfs4_proc_lookup(struct rpc_clnt *clnt, struct inode *dir,  	if (nfs_lookup_is_soft_revalidate(dentry))  		task_flags |= RPC_TASK_TIMEOUT; -	args.bitmask = nfs4_bitmask(server, label); +	args.bitmask = nfs4_bitmask(server, fattr->label);  	nfs_fattr_init(fattr); @@ -4347,7 +4318,7 @@ static void nfs_fixup_secinfo_attributes(struct nfs_fattr *fattr)  static int nfs4_proc_lookup_common(struct rpc_clnt **clnt, struct inode *dir,  				   struct dentry *dentry, struct nfs_fh *fhandle, -				   struct nfs_fattr *fattr, struct nfs4_label *label) +				   struct nfs_fattr *fattr)  {  	struct nfs4_exception exception = {  		.interruptible = true, @@ -4356,7 +4327,7 @@ static int nfs4_proc_lookup_common(struct rpc_clnt **clnt, struct inode *dir,  	const struct qstr *name = &dentry->d_name;  	int err;  	do { -		err = _nfs4_proc_lookup(client, dir, dentry, fhandle, fattr, label); +		err = _nfs4_proc_lookup(client, dir, dentry, fhandle, fattr);  		trace_nfs4_lookup(dir, name, err);  		switch (err) {  		case -NFS4ERR_BADNAME: @@ -4392,13 +4363,12 @@ out:  }  static int nfs4_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)  {  	int status;  	struct rpc_clnt *client = NFS_CLIENT(dir); -	status = nfs4_proc_lookup_common(&client, dir, dentry, fhandle, fattr, label); +	status = nfs4_proc_lookup_common(&client, dir, dentry, fhandle, fattr);  	if (client != NFS_CLIENT(dir)) {  		rpc_shutdown_client(client);  		nfs_fixup_secinfo_attributes(fattr); @@ -4413,15 +4383,14 @@ nfs4_proc_lookup_mountpoint(struct inode *dir, struct dentry *dentry,  	struct rpc_clnt *client = NFS_CLIENT(dir);  	int status; -	status = nfs4_proc_lookup_common(&client, dir, dentry, fhandle, fattr, NULL); +	status = nfs4_proc_lookup_common(&client, dir, dentry, fhandle, fattr);  	if (status < 0)  		return ERR_PTR(status);  	return (client == NFS_CLIENT(dir)) ? rpc_clone_client(client) : client;  }  static int _nfs4_proc_lookupp(struct inode *inode, -		struct nfs_fh *fhandle, struct nfs_fattr *fattr, -		struct nfs4_label *label) +		struct nfs_fh *fhandle, struct nfs_fattr *fattr)  {  	struct rpc_clnt *clnt = NFS_CLIENT(inode);  	struct nfs_server *server = NFS_SERVER(inode); @@ -4433,7 +4402,6 @@ static int _nfs4_proc_lookupp(struct inode *inode,  	struct nfs4_lookupp_res res = {  		.server = server,  		.fattr = fattr, -		.label = label,  		.fh = fhandle,  	};  	struct rpc_message msg = { @@ -4446,7 +4414,7 @@ static int _nfs4_proc_lookupp(struct inode *inode,  	if (NFS_SERVER(inode)->flags & NFS_MOUNT_SOFTREVAL)  		task_flags |= RPC_TASK_TIMEOUT; -	args.bitmask = nfs4_bitmask(server, label); +	args.bitmask = nfs4_bitmask(server, fattr->label);  	nfs_fattr_init(fattr); @@ -4458,14 +4426,14 @@ static int _nfs4_proc_lookupp(struct inode *inode,  }  static int nfs4_proc_lookupp(struct inode *inode, struct nfs_fh *fhandle, -			     struct nfs_fattr *fattr, struct nfs4_label *label) +			     struct nfs_fattr *fattr)  {  	struct nfs4_exception exception = {  		.interruptible = true,  	};  	int err;  	do { -		err = _nfs4_proc_lookupp(inode, fhandle, fattr, label); +		err = _nfs4_proc_lookupp(inode, fhandle, fattr);  		trace_nfs4_lookupp(inode, err);  		err = nfs4_handle_exception(NFS_SERVER(inode), err,  				&exception); @@ -4792,7 +4760,6 @@ static int _nfs4_proc_link(struct inode *inode, struct inode *dir, const struct  	};  	struct nfs4_link_res res = {  		.server = server, -		.label = NULL,  	};  	struct rpc_message msg = {  		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LINK], @@ -4801,18 +4768,12 @@ static int _nfs4_proc_link(struct inode *inode, struct inode *dir, const struct  	};  	int status = -ENOMEM; -	res.fattr = nfs_alloc_fattr(); +	res.fattr = nfs_alloc_fattr_with_label(server);  	if (res.fattr == NULL)  		goto out; -	res.label = nfs4_label_alloc(server, GFP_KERNEL); -	if (IS_ERR(res.label)) { -		status = PTR_ERR(res.label); -		goto out; -	} -  	nfs4_inode_make_writeable(inode); -	nfs4_bitmap_copy_adjust(bitmask, nfs4_bitmask(server, res.label), inode, +	nfs4_bitmap_copy_adjust(bitmask, nfs4_bitmask(server, res.fattr->label), inode,  				NFS_INO_INVALID_CHANGE);  	status = nfs4_call_sync(server->client, server, &msg, &arg.seq_args, &res.seq_res, 1);  	if (!status) { @@ -4821,12 +4782,9 @@ static int _nfs4_proc_link(struct inode *inode, struct inode *dir, const struct  		nfs4_inc_nlink(inode);  		status = nfs_post_op_update_inode(inode, res.fattr);  		if (!status) -			nfs_setsecurity(inode, res.fattr, res.label); +			nfs_setsecurity(inode, res.fattr);  	} - -	nfs4_label_free(res.label); -  out:  	nfs_free_fattr(res.fattr);  	return status; @@ -4852,7 +4810,6 @@ struct nfs4_createdata {  	struct nfs4_create_res res;  	struct nfs_fh fh;  	struct nfs_fattr fattr; -	struct nfs4_label *label;  };  static struct nfs4_createdata *nfs4_alloc_createdata(struct inode *dir, @@ -4864,8 +4821,8 @@ static struct nfs4_createdata *nfs4_alloc_createdata(struct inode *dir,  	if (data != NULL) {  		struct nfs_server *server = NFS_SERVER(dir); -		data->label = nfs4_label_alloc(server, GFP_KERNEL); -		if (IS_ERR(data->label)) +		data->fattr.label = nfs4_label_alloc(server, GFP_KERNEL); +		if (IS_ERR(data->fattr.label))  			goto out_free;  		data->msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CREATE]; @@ -4876,12 +4833,11 @@ static struct nfs4_createdata *nfs4_alloc_createdata(struct inode *dir,  		data->arg.name = name;  		data->arg.attrs = sattr;  		data->arg.ftype = ftype; -		data->arg.bitmask = nfs4_bitmask(server, data->label); +		data->arg.bitmask = nfs4_bitmask(server, data->fattr.label);  		data->arg.umask = current_umask();  		data->res.server = server;  		data->res.fh = &data->fh;  		data->res.fattr = &data->fattr; -		data->res.label = data->label;  		nfs_fattr_init(data->res.fattr);  	}  	return data; @@ -4903,14 +4859,14 @@ static int nfs4_do_create(struct inode *dir, struct dentry *dentry, struct nfs4_  					      data->res.fattr->time_start,  					      NFS_INO_INVALID_DATA);  		spin_unlock(&dir->i_lock); -		status = nfs_instantiate(dentry, data->res.fh, data->res.fattr, data->res.label); +		status = nfs_instantiate(dentry, data->res.fh, data->res.fattr);  	}  	return status;  }  static void nfs4_free_createdata(struct nfs4_createdata *data)  { -	nfs4_label_free(data->label); +	nfs4_label_free(data->fattr.label);  	kfree(data);  } @@ -5348,8 +5304,6 @@ static bool nfs4_read_plus_not_supported(struct rpc_task *task,  static int nfs4_read_done(struct rpc_task *task, struct nfs_pgio_header *hdr)  { -	dprintk("--> %s\n", __func__); -  	if (!nfs4_sequence_done(task, &hdr->res.seq_res))  		return -EAGAIN;  	if (nfs4_read_stateid_changed(task, &hdr->args)) @@ -6005,17 +5959,18 @@ static int _nfs4_get_security_label(struct inode *inode, void *buf,  					size_t buflen)  {  	struct nfs_server *server = NFS_SERVER(inode); -	struct nfs_fattr fattr;  	struct nfs4_label label = {0, 0, buflen, buf};  	u32 bitmask[3] = { 0, 0, FATTR4_WORD2_SECURITY_LABEL }; +	struct nfs_fattr fattr = { +		.label = &label, +	};  	struct nfs4_getattr_arg arg = {  		.fh		= NFS_FH(inode),  		.bitmask	= bitmask,  	};  	struct nfs4_getattr_res res = {  		.fattr		= &fattr, -		.label		= &label,  		.server		= server,  	};  	struct rpc_message msg = { @@ -6057,8 +6012,7 @@ static int nfs4_get_security_label(struct inode *inode, void *buf,  static int _nfs4_do_set_security_label(struct inode *inode,  		struct nfs4_label *ilabel, -		struct nfs_fattr *fattr, -		struct nfs4_label *olabel) +		struct nfs_fattr *fattr)  {  	struct iattr sattr = {0}; @@ -6073,7 +6027,6 @@ static int _nfs4_do_set_security_label(struct inode *inode,  	};  	struct nfs_setattrres res = {  		.fattr		= fattr, -		.label		= olabel,  		.server		= server,  	};  	struct rpc_message msg = { @@ -6094,15 +6047,13 @@ static int _nfs4_do_set_security_label(struct inode *inode,  static int nfs4_do_set_security_label(struct inode *inode,  		struct nfs4_label *ilabel, -		struct nfs_fattr *fattr, -		struct nfs4_label *olabel) +		struct nfs_fattr *fattr)  {  	struct nfs4_exception exception = { };  	int err;  	do { -		err = _nfs4_do_set_security_label(inode, ilabel, -				fattr, olabel); +		err = _nfs4_do_set_security_label(inode, ilabel, fattr);  		trace_nfs4_set_security_label(inode, err);  		err = nfs4_handle_exception(NFS_SERVER(inode), err,  				&exception); @@ -6113,32 +6064,21 @@ static int nfs4_do_set_security_label(struct inode *inode,  static int  nfs4_set_security_label(struct inode *inode, const void *buf, size_t buflen)  { -	struct nfs4_label ilabel, *olabel = NULL; -	struct nfs_fattr fattr; +	struct nfs4_label ilabel = {0, 0, buflen, (char *)buf }; +	struct nfs_fattr *fattr;  	int status;  	if (!nfs_server_capable(inode, NFS_CAP_SECURITY_LABEL))  		return -EOPNOTSUPP; -	nfs_fattr_init(&fattr); - -	ilabel.pi = 0; -	ilabel.lfs = 0; -	ilabel.label = (char *)buf; -	ilabel.len = buflen; - -	olabel = nfs4_label_alloc(NFS_SERVER(inode), GFP_KERNEL); -	if (IS_ERR(olabel)) { -		status = -PTR_ERR(olabel); -		goto out; -	} +	fattr = nfs_alloc_fattr_with_label(NFS_SERVER(inode)); +	if (fattr == NULL) +		return -ENOMEM; -	status = nfs4_do_set_security_label(inode, &ilabel, &fattr, olabel); +	status = nfs4_do_set_security_label(inode, &ilabel, fattr);  	if (status == 0) -		nfs_setsecurity(inode, &fattr, olabel); +		nfs_setsecurity(inode, fattr); -	nfs4_label_free(olabel); -out:  	return status;  }  #endif	/* CONFIG_NFS_V4_SECURITY_LABEL */ @@ -7004,7 +6944,6 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata)  	struct nfs4_lockdata *data = calldata;  	struct nfs4_state *state = data->lsp->ls_state; -	dprintk("%s: begin!\n", __func__);  	if (nfs_wait_on_sequence(data->arg.lock_seqid, task) != 0)  		goto out_wait;  	/* Do we need to do an open_to_lock_owner? */ @@ -7038,7 +6977,7 @@ out_release_lock_seqid:  	nfs_release_seqid(data->arg.lock_seqid);  out_wait:  	nfs4_sequence_done(task, &data->res.seq_res); -	dprintk("%s: done!, ret = %d\n", __func__, data->rpc_status); +	dprintk("%s: ret = %d\n", __func__, data->rpc_status);  }  static void nfs4_lock_done(struct rpc_task *task, void *calldata) @@ -7046,8 +6985,6 @@ static void nfs4_lock_done(struct rpc_task *task, void *calldata)  	struct nfs4_lockdata *data = calldata;  	struct nfs4_lock_state *lsp = data->lsp; -	dprintk("%s: begin!\n", __func__); -  	if (!nfs4_sequence_done(task, &data->res.seq_res))  		return; @@ -7081,7 +7018,7 @@ static void nfs4_lock_done(struct rpc_task *task, void *calldata)  				goto out_restart;  	}  out_done: -	dprintk("%s: done, ret = %d!\n", __func__, data->rpc_status); +	dprintk("%s: ret = %d!\n", __func__, data->rpc_status);  	return;  out_restart:  	if (!data->cancelled) @@ -7093,7 +7030,6 @@ static void nfs4_lock_release(void *calldata)  {  	struct nfs4_lockdata *data = calldata; -	dprintk("%s: begin!\n", __func__);  	nfs_free_seqid(data->arg.open_seqid);  	if (data->cancelled && data->rpc_status == 0) {  		struct rpc_task *task; @@ -7107,7 +7043,6 @@ static void nfs4_lock_release(void *calldata)  	nfs4_put_lock_state(data->lsp);  	put_nfs_open_context(data->ctx);  	kfree(data); -	dprintk("%s: done!\n", __func__);  }  static const struct rpc_call_ops nfs4_lock_ops = { @@ -7154,7 +7089,6 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *f  	if (client->cl_minorversion)  		task_setup_data.flags |= RPC_TASK_MOVEABLE; -	dprintk("%s: begin!\n", __func__);  	data = nfs4_alloc_lockdata(fl, nfs_file_open_context(fl->fl_file),  			fl->fl_u.nfs4_fl.owner,  			recovery_type == NFS_LOCK_NEW ? GFP_KERNEL : GFP_NOFS); @@ -7185,7 +7119,7 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *f  		data->cancelled = true;  	trace_nfs4_set_lock(fl, state, &data->res.stateid, cmd, ret);  	rpc_put_task(task); -	dprintk("%s: done, ret = %d!\n", __func__, ret); +	dprintk("%s: ret = %d\n", __func__, ret);  	return ret;  } @@ -8856,14 +8790,12 @@ static void nfs4_get_lease_time_prepare(struct rpc_task *task,  	struct nfs4_get_lease_time_data *data =  			(struct nfs4_get_lease_time_data *)calldata; -	dprintk("--> %s\n", __func__);  	/* just setup sequence, do not trigger session recovery  	   since we're invoked within one */  	nfs4_setup_sequence(data->clp,  			&data->args->la_seq_args,  			&data->res->lr_seq_res,  			task); -	dprintk("<-- %s\n", __func__);  }  /* @@ -8875,13 +8807,11 @@ static void nfs4_get_lease_time_done(struct rpc_task *task, void *calldata)  	struct nfs4_get_lease_time_data *data =  			(struct nfs4_get_lease_time_data *)calldata; -	dprintk("--> %s\n", __func__);  	if (!nfs4_sequence_done(task, &data->res->lr_seq_res))  		return;  	switch (task->tk_status) {  	case -NFS4ERR_DELAY:  	case -NFS4ERR_GRACE: -		dprintk("%s Retry: tk_status %d\n", __func__, task->tk_status);  		rpc_delay(task, NFS4_POLL_RETRY_MIN);  		task->tk_status = 0;  		fallthrough; @@ -8889,7 +8819,6 @@ static void nfs4_get_lease_time_done(struct rpc_task *task, void *calldata)  		rpc_restart_call_prepare(task);  		return;  	} -	dprintk("<-- %s\n", __func__);  }  static const struct rpc_call_ops nfs4_get_lease_time_ops = { @@ -9121,7 +9050,6 @@ int nfs4_proc_create_session(struct nfs_client *clp, const struct cred *cred)  	dprintk("%s client>seqid %d sessionid %u:%u:%u:%u\n", __func__,  		clp->cl_seqid, ptr[0], ptr[1], ptr[2], ptr[3]);  out: -	dprintk("<-- %s\n", __func__);  	return status;  } @@ -9139,8 +9067,6 @@ int nfs4_proc_destroy_session(struct nfs4_session *session,  	};  	int status = 0; -	dprintk("--> nfs4_proc_destroy_session\n"); -  	/* session is still being setup */  	if (!test_and_clear_bit(NFS4_SESSION_ESTABLISHED, &session->session_state))  		return 0; @@ -9152,8 +9078,6 @@ int nfs4_proc_destroy_session(struct nfs4_session *session,  	if (status)  		dprintk("NFS: Got error %d from the server on DESTROY_SESSION. "  			"Session has been destroyed regardless...\n", status); - -	dprintk("<-- nfs4_proc_destroy_session\n");  	return status;  } @@ -9201,7 +9125,7 @@ static void nfs41_sequence_call_done(struct rpc_task *task, void *data)  	if (task->tk_status < 0) {  		dprintk("%s ERROR %d\n", __func__, task->tk_status);  		if (refcount_read(&clp->cl_count) == 1) -			goto out; +			return;  		if (nfs41_sequence_handle_errors(task, clp) == -EAGAIN) {  			rpc_restart_call_prepare(task); @@ -9209,8 +9133,6 @@ static void nfs41_sequence_call_done(struct rpc_task *task, void *data)  		}  	}  	dprintk("%s rpc_cred %p\n", __func__, task->tk_msg.rpc_cred); -out: -	dprintk("<-- %s\n", __func__);  }  static void nfs41_sequence_prepare(struct rpc_task *task, void *data) @@ -9357,7 +9279,6 @@ static void nfs4_reclaim_complete_done(struct rpc_task *task, void *data)  	struct nfs_client *clp = calldata->clp;  	struct nfs4_sequence_res *res = &calldata->res.seq_res; -	dprintk("--> %s\n", __func__);  	if (!nfs41_sequence_done(task, res))  		return; @@ -9366,7 +9287,6 @@ static void nfs4_reclaim_complete_done(struct rpc_task *task, void *data)  		rpc_restart_call_prepare(task);  		return;  	} -	dprintk("<-- %s\n", __func__);  }  static void nfs4_free_reclaim_complete_data(void *data) @@ -9401,7 +9321,6 @@ static int nfs41_proc_reclaim_complete(struct nfs_client *clp,  	};  	int status = -ENOMEM; -	dprintk("--> %s\n", __func__);  	calldata = kzalloc(sizeof(*calldata), GFP_NOFS);  	if (calldata == NULL)  		goto out; @@ -9424,19 +9343,15 @@ nfs4_layoutget_prepare(struct rpc_task *task, void *calldata)  	struct nfs4_layoutget *lgp = calldata;  	struct nfs_server *server = NFS_SERVER(lgp->args.inode); -	dprintk("--> %s\n", __func__);  	nfs4_setup_sequence(server->nfs_client, &lgp->args.seq_args,  				&lgp->res.seq_res, task); -	dprintk("<-- %s\n", __func__);  }  static void nfs4_layoutget_done(struct rpc_task *task, void *calldata)  {  	struct nfs4_layoutget *lgp = calldata; -	dprintk("--> %s\n", __func__);  	nfs41_sequence_process(task, &lgp->res.seq_res); -	dprintk("<-- %s\n", __func__);  }  static int @@ -9525,7 +9440,6 @@ nfs4_layoutget_handle_exception(struct rpc_task *task,  			status = err;  	}  out: -	dprintk("<-- %s\n", __func__);  	return status;  } @@ -9539,10 +9453,8 @@ static void nfs4_layoutget_release(void *calldata)  {  	struct nfs4_layoutget *lgp = calldata; -	dprintk("--> %s\n", __func__);  	nfs4_sequence_free_slot(&lgp->res.seq_res);  	pnfs_layoutget_free(lgp); -	dprintk("<-- %s\n", __func__);  }  static const struct rpc_call_ops nfs4_layoutget_call_ops = { @@ -9578,8 +9490,6 @@ nfs4_proc_layoutget(struct nfs4_layoutget *lgp, long *timeout)  	};  	int status = 0; -	dprintk("--> %s\n", __func__); -  	nfs4_init_sequence(&lgp->args.seq_args, &lgp->res.seq_res, 0, 0);  	task = rpc_run_task(&task_setup_data); @@ -9615,7 +9525,6 @@ nfs4_layoutreturn_prepare(struct rpc_task *task, void *calldata)  {  	struct nfs4_layoutreturn *lrp = calldata; -	dprintk("--> %s\n", __func__);  	nfs4_setup_sequence(lrp->clp,  			&lrp->args.seq_args,  			&lrp->res.seq_res, @@ -9629,8 +9538,6 @@ static void nfs4_layoutreturn_done(struct rpc_task *task, void *calldata)  	struct nfs4_layoutreturn *lrp = calldata;  	struct nfs_server *server; -	dprintk("--> %s\n", __func__); -  	if (!nfs41_sequence_process(task, &lrp->res.seq_res))  		return; @@ -9661,7 +9568,6 @@ static void nfs4_layoutreturn_done(struct rpc_task *task, void *calldata)  			break;  		goto out_restart;  	} -	dprintk("<-- %s\n", __func__);  	return;  out_restart:  	task->tk_status = 0; @@ -9674,7 +9580,6 @@ static void nfs4_layoutreturn_release(void *calldata)  	struct nfs4_layoutreturn *lrp = calldata;  	struct pnfs_layout_hdr *lo = lrp->args.layout; -	dprintk("--> %s\n", __func__);  	pnfs_layoutreturn_free_lsegs(lo, &lrp->args.stateid, &lrp->args.range,  			lrp->res.lrs_present ? &lrp->res.stateid : NULL);  	nfs4_sequence_free_slot(&lrp->res.seq_res); @@ -9684,7 +9589,6 @@ static void nfs4_layoutreturn_release(void *calldata)  	nfs_iput_and_deactive(lrp->inode);  	put_cred(lrp->cred);  	kfree(calldata); -	dprintk("<-- %s\n", __func__);  }  static const struct rpc_call_ops nfs4_layoutreturn_call_ops = { @@ -9715,7 +9619,6 @@ int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp, bool sync)  			NFS_SP4_MACH_CRED_PNFS_CLEANUP,  			&task_setup_data.rpc_client, &msg); -	dprintk("--> %s\n", __func__);  	lrp->inode = nfs_igrab_and_active(lrp->args.inode);  	if (!sync) {  		if (!lrp->inode) { @@ -9762,7 +9665,6 @@ _nfs4_proc_getdeviceinfo(struct nfs_server *server,  	};  	int status; -	dprintk("--> %s\n", __func__);  	status = nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0);  	if (res.notification & ~args.notify_types)  		dprintk("%s: unsupported notification\n", __func__); @@ -9934,7 +9836,6 @@ _nfs41_proc_secinfo_no_name(struct nfs_server *server, struct nfs_fh *fhandle,  		msg.rpc_cred = cred;  	} -	dprintk("--> %s\n", __func__);  	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); @@ -10158,6 +10059,10 @@ static void nfs41_free_stateid_done(struct rpc_task *task, void *calldata)  static void nfs41_free_stateid_release(void *calldata)  { +	struct nfs_free_stateid_data *data = calldata; +	struct nfs_client *clp = data->server->nfs_client; + +	nfs_put_client(clp);  	kfree(calldata);  } @@ -10194,6 +10099,10 @@ static int nfs41_free_stateid(struct nfs_server *server,  	};  	struct nfs_free_stateid_data *data;  	struct rpc_task *task; +	struct nfs_client *clp = server->nfs_client; + +	if (!refcount_inc_not_zero(&clp->cl_count)) +		return -EIO;  	nfs4_state_protect(server->nfs_client, NFS_SP4_MACH_CRED_STATEID,  		&task_setup.rpc_client, &msg); diff --git a/fs/nfs/nfs4session.c b/fs/nfs/nfs4session.c index 4145a0138907..5db460476bf2 100644 --- a/fs/nfs/nfs4session.c +++ b/fs/nfs/nfs4session.c @@ -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);  } diff --git a/fs/nfs/nfs4session.h b/fs/nfs/nfs4session.h index 3de425f59b3a..351616c61df5 100644 --- a/fs/nfs/nfs4session.h +++ b/fs/nfs/nfs4session.h @@ -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) diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index f22818a80c2c..ecc4594299d6 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c @@ -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);  } diff --git a/fs/nfs/nfs4trace.h b/fs/nfs/nfs4trace.h index 7a2567aa2b86..6ee6ad3674a2 100644 --- a/fs/nfs/nfs4trace.h +++ b/fs/nfs/nfs4trace.h @@ -9,322 +9,10 @@  #define _TRACE_NFS4_H  #include <linux/tracepoint.h> +#include <trace/events/sunrpc_base.h> -TRACE_DEFINE_ENUM(EPERM); -TRACE_DEFINE_ENUM(ENOENT); -TRACE_DEFINE_ENUM(EIO); -TRACE_DEFINE_ENUM(ENXIO); -TRACE_DEFINE_ENUM(EACCES); -TRACE_DEFINE_ENUM(EEXIST); -TRACE_DEFINE_ENUM(EXDEV); -TRACE_DEFINE_ENUM(ENOTDIR); -TRACE_DEFINE_ENUM(EISDIR); -TRACE_DEFINE_ENUM(EFBIG); -TRACE_DEFINE_ENUM(ENOSPC); -TRACE_DEFINE_ENUM(EROFS); -TRACE_DEFINE_ENUM(EMLINK); -TRACE_DEFINE_ENUM(ENAMETOOLONG); -TRACE_DEFINE_ENUM(ENOTEMPTY); -TRACE_DEFINE_ENUM(EDQUOT); -TRACE_DEFINE_ENUM(ESTALE); -TRACE_DEFINE_ENUM(EBADHANDLE); -TRACE_DEFINE_ENUM(EBADCOOKIE); -TRACE_DEFINE_ENUM(ENOTSUPP); -TRACE_DEFINE_ENUM(ETOOSMALL); -TRACE_DEFINE_ENUM(EREMOTEIO); -TRACE_DEFINE_ENUM(EBADTYPE); -TRACE_DEFINE_ENUM(EAGAIN); -TRACE_DEFINE_ENUM(ELOOP); -TRACE_DEFINE_ENUM(EOPNOTSUPP); -TRACE_DEFINE_ENUM(EDEADLK); -TRACE_DEFINE_ENUM(ENOMEM); -TRACE_DEFINE_ENUM(EKEYEXPIRED); -TRACE_DEFINE_ENUM(ETIMEDOUT); -TRACE_DEFINE_ENUM(ERESTARTSYS); -TRACE_DEFINE_ENUM(ECONNREFUSED); -TRACE_DEFINE_ENUM(ECONNRESET); -TRACE_DEFINE_ENUM(ENETUNREACH); -TRACE_DEFINE_ENUM(EHOSTUNREACH); -TRACE_DEFINE_ENUM(EHOSTDOWN); -TRACE_DEFINE_ENUM(EPIPE); -TRACE_DEFINE_ENUM(EPFNOSUPPORT); -TRACE_DEFINE_ENUM(EPROTONOSUPPORT); - -TRACE_DEFINE_ENUM(NFS4_OK); -TRACE_DEFINE_ENUM(NFS4ERR_ACCESS); -TRACE_DEFINE_ENUM(NFS4ERR_ATTRNOTSUPP); -TRACE_DEFINE_ENUM(NFS4ERR_ADMIN_REVOKED); -TRACE_DEFINE_ENUM(NFS4ERR_BACK_CHAN_BUSY); -TRACE_DEFINE_ENUM(NFS4ERR_BADCHAR); -TRACE_DEFINE_ENUM(NFS4ERR_BADHANDLE); -TRACE_DEFINE_ENUM(NFS4ERR_BADIOMODE); -TRACE_DEFINE_ENUM(NFS4ERR_BADLAYOUT); -TRACE_DEFINE_ENUM(NFS4ERR_BADLABEL); -TRACE_DEFINE_ENUM(NFS4ERR_BADNAME); -TRACE_DEFINE_ENUM(NFS4ERR_BADOWNER); -TRACE_DEFINE_ENUM(NFS4ERR_BADSESSION); -TRACE_DEFINE_ENUM(NFS4ERR_BADSLOT); -TRACE_DEFINE_ENUM(NFS4ERR_BADTYPE); -TRACE_DEFINE_ENUM(NFS4ERR_BADXDR); -TRACE_DEFINE_ENUM(NFS4ERR_BAD_COOKIE); -TRACE_DEFINE_ENUM(NFS4ERR_BAD_HIGH_SLOT); -TRACE_DEFINE_ENUM(NFS4ERR_BAD_RANGE); -TRACE_DEFINE_ENUM(NFS4ERR_BAD_SEQID); -TRACE_DEFINE_ENUM(NFS4ERR_BAD_SESSION_DIGEST); -TRACE_DEFINE_ENUM(NFS4ERR_BAD_STATEID); -TRACE_DEFINE_ENUM(NFS4ERR_CB_PATH_DOWN); -TRACE_DEFINE_ENUM(NFS4ERR_CLID_INUSE); -TRACE_DEFINE_ENUM(NFS4ERR_CLIENTID_BUSY); -TRACE_DEFINE_ENUM(NFS4ERR_COMPLETE_ALREADY); -TRACE_DEFINE_ENUM(NFS4ERR_CONN_NOT_BOUND_TO_SESSION); -TRACE_DEFINE_ENUM(NFS4ERR_DEADLOCK); -TRACE_DEFINE_ENUM(NFS4ERR_DEADSESSION); -TRACE_DEFINE_ENUM(NFS4ERR_DELAY); -TRACE_DEFINE_ENUM(NFS4ERR_DELEG_ALREADY_WANTED); -TRACE_DEFINE_ENUM(NFS4ERR_DELEG_REVOKED); -TRACE_DEFINE_ENUM(NFS4ERR_DENIED); -TRACE_DEFINE_ENUM(NFS4ERR_DIRDELEG_UNAVAIL); -TRACE_DEFINE_ENUM(NFS4ERR_DQUOT); -TRACE_DEFINE_ENUM(NFS4ERR_ENCR_ALG_UNSUPP); -TRACE_DEFINE_ENUM(NFS4ERR_EXIST); -TRACE_DEFINE_ENUM(NFS4ERR_EXPIRED); -TRACE_DEFINE_ENUM(NFS4ERR_FBIG); -TRACE_DEFINE_ENUM(NFS4ERR_FHEXPIRED); -TRACE_DEFINE_ENUM(NFS4ERR_FILE_OPEN); -TRACE_DEFINE_ENUM(NFS4ERR_GRACE); -TRACE_DEFINE_ENUM(NFS4ERR_HASH_ALG_UNSUPP); -TRACE_DEFINE_ENUM(NFS4ERR_INVAL); -TRACE_DEFINE_ENUM(NFS4ERR_IO); -TRACE_DEFINE_ENUM(NFS4ERR_ISDIR); -TRACE_DEFINE_ENUM(NFS4ERR_LAYOUTTRYLATER); -TRACE_DEFINE_ENUM(NFS4ERR_LAYOUTUNAVAILABLE); -TRACE_DEFINE_ENUM(NFS4ERR_LEASE_MOVED); -TRACE_DEFINE_ENUM(NFS4ERR_LOCKED); -TRACE_DEFINE_ENUM(NFS4ERR_LOCKS_HELD); -TRACE_DEFINE_ENUM(NFS4ERR_LOCK_RANGE); -TRACE_DEFINE_ENUM(NFS4ERR_MINOR_VERS_MISMATCH); -TRACE_DEFINE_ENUM(NFS4ERR_MLINK); -TRACE_DEFINE_ENUM(NFS4ERR_MOVED); -TRACE_DEFINE_ENUM(NFS4ERR_NAMETOOLONG); -TRACE_DEFINE_ENUM(NFS4ERR_NOENT); -TRACE_DEFINE_ENUM(NFS4ERR_NOFILEHANDLE); -TRACE_DEFINE_ENUM(NFS4ERR_NOMATCHING_LAYOUT); -TRACE_DEFINE_ENUM(NFS4ERR_NOSPC); -TRACE_DEFINE_ENUM(NFS4ERR_NOTDIR); -TRACE_DEFINE_ENUM(NFS4ERR_NOTEMPTY); -TRACE_DEFINE_ENUM(NFS4ERR_NOTSUPP); -TRACE_DEFINE_ENUM(NFS4ERR_NOT_ONLY_OP); -TRACE_DEFINE_ENUM(NFS4ERR_NOT_SAME); -TRACE_DEFINE_ENUM(NFS4ERR_NO_GRACE); -TRACE_DEFINE_ENUM(NFS4ERR_NXIO); -TRACE_DEFINE_ENUM(NFS4ERR_OLD_STATEID); -TRACE_DEFINE_ENUM(NFS4ERR_OPENMODE); -TRACE_DEFINE_ENUM(NFS4ERR_OP_ILLEGAL); -TRACE_DEFINE_ENUM(NFS4ERR_OP_NOT_IN_SESSION); -TRACE_DEFINE_ENUM(NFS4ERR_PERM); -TRACE_DEFINE_ENUM(NFS4ERR_PNFS_IO_HOLE); -TRACE_DEFINE_ENUM(NFS4ERR_PNFS_NO_LAYOUT); -TRACE_DEFINE_ENUM(NFS4ERR_RECALLCONFLICT); -TRACE_DEFINE_ENUM(NFS4ERR_RECLAIM_BAD); -TRACE_DEFINE_ENUM(NFS4ERR_RECLAIM_CONFLICT); -TRACE_DEFINE_ENUM(NFS4ERR_REJECT_DELEG); -TRACE_DEFINE_ENUM(NFS4ERR_REP_TOO_BIG); -TRACE_DEFINE_ENUM(NFS4ERR_REP_TOO_BIG_TO_CACHE); -TRACE_DEFINE_ENUM(NFS4ERR_REQ_TOO_BIG); -TRACE_DEFINE_ENUM(NFS4ERR_RESOURCE); -TRACE_DEFINE_ENUM(NFS4ERR_RESTOREFH); -TRACE_DEFINE_ENUM(NFS4ERR_RETRY_UNCACHED_REP); -TRACE_DEFINE_ENUM(NFS4ERR_RETURNCONFLICT); -TRACE_DEFINE_ENUM(NFS4ERR_ROFS); -TRACE_DEFINE_ENUM(NFS4ERR_SAME); -TRACE_DEFINE_ENUM(NFS4ERR_SHARE_DENIED); -TRACE_DEFINE_ENUM(NFS4ERR_SEQUENCE_POS); -TRACE_DEFINE_ENUM(NFS4ERR_SEQ_FALSE_RETRY); -TRACE_DEFINE_ENUM(NFS4ERR_SEQ_MISORDERED); -TRACE_DEFINE_ENUM(NFS4ERR_SERVERFAULT); -TRACE_DEFINE_ENUM(NFS4ERR_STALE); -TRACE_DEFINE_ENUM(NFS4ERR_STALE_CLIENTID); -TRACE_DEFINE_ENUM(NFS4ERR_STALE_STATEID); -TRACE_DEFINE_ENUM(NFS4ERR_SYMLINK); -TRACE_DEFINE_ENUM(NFS4ERR_TOOSMALL); -TRACE_DEFINE_ENUM(NFS4ERR_TOO_MANY_OPS); -TRACE_DEFINE_ENUM(NFS4ERR_UNKNOWN_LAYOUTTYPE); -TRACE_DEFINE_ENUM(NFS4ERR_UNSAFE_COMPOUND); -TRACE_DEFINE_ENUM(NFS4ERR_WRONGSEC); -TRACE_DEFINE_ENUM(NFS4ERR_WRONG_CRED); -TRACE_DEFINE_ENUM(NFS4ERR_WRONG_TYPE); -TRACE_DEFINE_ENUM(NFS4ERR_XDEV); - -TRACE_DEFINE_ENUM(NFS4ERR_RESET_TO_MDS); -TRACE_DEFINE_ENUM(NFS4ERR_RESET_TO_PNFS); - -#define show_nfsv4_errors(error) \ -	__print_symbolic(error, \ -		{ NFS4_OK, "OK" }, \ -		/* Mapped by nfs4_stat_to_errno() */ \ -		{ EPERM, "EPERM" }, \ -		{ ENOENT, "ENOENT" }, \ -		{ EIO, "EIO" }, \ -		{ ENXIO, "ENXIO" }, \ -		{ EACCES, "EACCES" }, \ -		{ EEXIST, "EEXIST" }, \ -		{ EXDEV, "EXDEV" }, \ -		{ ENOTDIR, "ENOTDIR" }, \ -		{ EISDIR, "EISDIR" }, \ -		{ EFBIG, "EFBIG" }, \ -		{ ENOSPC, "ENOSPC" }, \ -		{ EROFS, "EROFS" }, \ -		{ EMLINK, "EMLINK" }, \ -		{ ENAMETOOLONG, "ENAMETOOLONG" }, \ -		{ ENOTEMPTY, "ENOTEMPTY" }, \ -		{ EDQUOT, "EDQUOT" }, \ -		{ ESTALE, "ESTALE" }, \ -		{ EBADHANDLE, "EBADHANDLE" }, \ -		{ EBADCOOKIE, "EBADCOOKIE" }, \ -		{ ENOTSUPP, "ENOTSUPP" }, \ -		{ ETOOSMALL, "ETOOSMALL" }, \ -		{ EREMOTEIO, "EREMOTEIO" }, \ -		{ EBADTYPE, "EBADTYPE" }, \ -		{ EAGAIN, "EAGAIN" }, \ -		{ ELOOP, "ELOOP" }, \ -		{ EOPNOTSUPP, "EOPNOTSUPP" }, \ -		{ EDEADLK, "EDEADLK" }, \ -		/* RPC errors */ \ -		{ ENOMEM, "ENOMEM" }, \ -		{ EKEYEXPIRED, "EKEYEXPIRED" }, \ -		{ ETIMEDOUT, "ETIMEDOUT" }, \ -		{ ERESTARTSYS, "ERESTARTSYS" }, \ -		{ ECONNREFUSED, "ECONNREFUSED" }, \ -		{ ECONNRESET, "ECONNRESET" }, \ -		{ ENETUNREACH, "ENETUNREACH" }, \ -		{ EHOSTUNREACH, "EHOSTUNREACH" }, \ -		{ EHOSTDOWN, "EHOSTDOWN" }, \ -		{ EPIPE, "EPIPE" }, \ -		{ EPFNOSUPPORT, "EPFNOSUPPORT" }, \ -		{ EPROTONOSUPPORT, "EPROTONOSUPPORT" }, \ -		/* NFSv4 native errors */ \ -		{ NFS4ERR_ACCESS, "ACCESS" }, \ -		{ NFS4ERR_ATTRNOTSUPP, "ATTRNOTSUPP" }, \ -		{ NFS4ERR_ADMIN_REVOKED, "ADMIN_REVOKED" }, \ -		{ NFS4ERR_BACK_CHAN_BUSY, "BACK_CHAN_BUSY" }, \ -		{ NFS4ERR_BADCHAR, "BADCHAR" }, \ -		{ NFS4ERR_BADHANDLE, "BADHANDLE" }, \ -		{ NFS4ERR_BADIOMODE, "BADIOMODE" }, \ -		{ NFS4ERR_BADLAYOUT, "BADLAYOUT" }, \ -		{ NFS4ERR_BADLABEL, "BADLABEL" }, \ -		{ NFS4ERR_BADNAME, "BADNAME" }, \ -		{ NFS4ERR_BADOWNER, "BADOWNER" }, \ -		{ NFS4ERR_BADSESSION, "BADSESSION" }, \ -		{ NFS4ERR_BADSLOT, "BADSLOT" }, \ -		{ NFS4ERR_BADTYPE, "BADTYPE" }, \ -		{ NFS4ERR_BADXDR, "BADXDR" }, \ -		{ NFS4ERR_BAD_COOKIE, "BAD_COOKIE" }, \ -		{ NFS4ERR_BAD_HIGH_SLOT, "BAD_HIGH_SLOT" }, \ -		{ NFS4ERR_BAD_RANGE, "BAD_RANGE" }, \ -		{ NFS4ERR_BAD_SEQID, "BAD_SEQID" }, \ -		{ NFS4ERR_BAD_SESSION_DIGEST, "BAD_SESSION_DIGEST" }, \ -		{ NFS4ERR_BAD_STATEID, "BAD_STATEID" }, \ -		{ NFS4ERR_CB_PATH_DOWN, "CB_PATH_DOWN" }, \ -		{ NFS4ERR_CLID_INUSE, "CLID_INUSE" }, \ -		{ NFS4ERR_CLIENTID_BUSY, "CLIENTID_BUSY" }, \ -		{ NFS4ERR_COMPLETE_ALREADY, "COMPLETE_ALREADY" }, \ -		{ NFS4ERR_CONN_NOT_BOUND_TO_SESSION, \ -			"CONN_NOT_BOUND_TO_SESSION" }, \ -		{ NFS4ERR_DEADLOCK, "DEADLOCK" }, \ -		{ NFS4ERR_DEADSESSION, "DEAD_SESSION" }, \ -		{ NFS4ERR_DELAY, "DELAY" }, \ -		{ NFS4ERR_DELEG_ALREADY_WANTED, \ -			"DELEG_ALREADY_WANTED" }, \ -		{ NFS4ERR_DELEG_REVOKED, "DELEG_REVOKED" }, \ -		{ NFS4ERR_DENIED, "DENIED" }, \ -		{ NFS4ERR_DIRDELEG_UNAVAIL, "DIRDELEG_UNAVAIL" }, \ -		{ NFS4ERR_DQUOT, "DQUOT" }, \ -		{ NFS4ERR_ENCR_ALG_UNSUPP, "ENCR_ALG_UNSUPP" }, \ -		{ NFS4ERR_EXIST, "EXIST" }, \ -		{ NFS4ERR_EXPIRED, "EXPIRED" }, \ -		{ NFS4ERR_FBIG, "FBIG" }, \ -		{ NFS4ERR_FHEXPIRED, "FHEXPIRED" }, \ -		{ NFS4ERR_FILE_OPEN, "FILE_OPEN" }, \ -		{ NFS4ERR_GRACE, "GRACE" }, \ -		{ NFS4ERR_HASH_ALG_UNSUPP, "HASH_ALG_UNSUPP" }, \ -		{ NFS4ERR_INVAL, "INVAL" }, \ -		{ NFS4ERR_IO, "IO" }, \ -		{ NFS4ERR_ISDIR, "ISDIR" }, \ -		{ NFS4ERR_LAYOUTTRYLATER, "LAYOUTTRYLATER" }, \ -		{ NFS4ERR_LAYOUTUNAVAILABLE, "LAYOUTUNAVAILABLE" }, \ -		{ NFS4ERR_LEASE_MOVED, "LEASE_MOVED" }, \ -		{ NFS4ERR_LOCKED, "LOCKED" }, \ -		{ NFS4ERR_LOCKS_HELD, "LOCKS_HELD" }, \ -		{ NFS4ERR_LOCK_RANGE, "LOCK_RANGE" }, \ -		{ NFS4ERR_MINOR_VERS_MISMATCH, "MINOR_VERS_MISMATCH" }, \ -		{ NFS4ERR_MLINK, "MLINK" }, \ -		{ NFS4ERR_MOVED, "MOVED" }, \ -		{ NFS4ERR_NAMETOOLONG, "NAMETOOLONG" }, \ -		{ NFS4ERR_NOENT, "NOENT" }, \ -		{ NFS4ERR_NOFILEHANDLE, "NOFILEHANDLE" }, \ -		{ NFS4ERR_NOMATCHING_LAYOUT, "NOMATCHING_LAYOUT" }, \ -		{ NFS4ERR_NOSPC, "NOSPC" }, \ -		{ NFS4ERR_NOTDIR, "NOTDIR" }, \ -		{ NFS4ERR_NOTEMPTY, "NOTEMPTY" }, \ -		{ NFS4ERR_NOTSUPP, "NOTSUPP" }, \ -		{ NFS4ERR_NOT_ONLY_OP, "NOT_ONLY_OP" }, \ -		{ NFS4ERR_NOT_SAME, "NOT_SAME" }, \ -		{ NFS4ERR_NO_GRACE, "NO_GRACE" }, \ -		{ NFS4ERR_NXIO, "NXIO" }, \ -		{ NFS4ERR_OLD_STATEID, "OLD_STATEID" }, \ -		{ NFS4ERR_OPENMODE, "OPENMODE" }, \ -		{ NFS4ERR_OP_ILLEGAL, "OP_ILLEGAL" }, \ -		{ NFS4ERR_OP_NOT_IN_SESSION, "OP_NOT_IN_SESSION" }, \ -		{ NFS4ERR_PERM, "PERM" }, \ -		{ NFS4ERR_PNFS_IO_HOLE, "PNFS_IO_HOLE" }, \ -		{ NFS4ERR_PNFS_NO_LAYOUT, "PNFS_NO_LAYOUT" }, \ -		{ NFS4ERR_RECALLCONFLICT, "RECALLCONFLICT" }, \ -		{ NFS4ERR_RECLAIM_BAD, "RECLAIM_BAD" }, \ -		{ NFS4ERR_RECLAIM_CONFLICT, "RECLAIM_CONFLICT" }, \ -		{ NFS4ERR_REJECT_DELEG, "REJECT_DELEG" }, \ -		{ NFS4ERR_REP_TOO_BIG, "REP_TOO_BIG" }, \ -		{ NFS4ERR_REP_TOO_BIG_TO_CACHE, \ -			"REP_TOO_BIG_TO_CACHE" }, \ -		{ NFS4ERR_REQ_TOO_BIG, "REQ_TOO_BIG" }, \ -		{ NFS4ERR_RESOURCE, "RESOURCE" }, \ -		{ NFS4ERR_RESTOREFH, "RESTOREFH" }, \ -		{ NFS4ERR_RETRY_UNCACHED_REP, "RETRY_UNCACHED_REP" }, \ -		{ NFS4ERR_RETURNCONFLICT, "RETURNCONFLICT" }, \ -		{ NFS4ERR_ROFS, "ROFS" }, \ -		{ NFS4ERR_SAME, "SAME" }, \ -		{ NFS4ERR_SHARE_DENIED, "SHARE_DENIED" }, \ -		{ NFS4ERR_SEQUENCE_POS, "SEQUENCE_POS" }, \ -		{ NFS4ERR_SEQ_FALSE_RETRY, "SEQ_FALSE_RETRY" }, \ -		{ NFS4ERR_SEQ_MISORDERED, "SEQ_MISORDERED" }, \ -		{ NFS4ERR_SERVERFAULT, "SERVERFAULT" }, \ -		{ NFS4ERR_STALE, "STALE" }, \ -		{ NFS4ERR_STALE_CLIENTID, "STALE_CLIENTID" }, \ -		{ NFS4ERR_STALE_STATEID, "STALE_STATEID" }, \ -		{ NFS4ERR_SYMLINK, "SYMLINK" }, \ -		{ NFS4ERR_TOOSMALL, "TOOSMALL" }, \ -		{ NFS4ERR_TOO_MANY_OPS, "TOO_MANY_OPS" }, \ -		{ NFS4ERR_UNKNOWN_LAYOUTTYPE, "UNKNOWN_LAYOUTTYPE" }, \ -		{ NFS4ERR_UNSAFE_COMPOUND, "UNSAFE_COMPOUND" }, \ -		{ NFS4ERR_WRONGSEC, "WRONGSEC" }, \ -		{ NFS4ERR_WRONG_CRED, "WRONG_CRED" }, \ -		{ NFS4ERR_WRONG_TYPE, "WRONG_TYPE" }, \ -		{ NFS4ERR_XDEV, "XDEV" }, \ -		/* ***** Internal to Linux NFS client ***** */ \ -		{ NFS4ERR_RESET_TO_MDS, "RESET_TO_MDS" }, \ -		{ NFS4ERR_RESET_TO_PNFS, "RESET_TO_PNFS" }) - -#define show_open_flags(flags) \ -	__print_flags(flags, "|", \ -		{ O_CREAT, "O_CREAT" }, \ -		{ O_EXCL, "O_EXCL" }, \ -		{ O_TRUNC, "O_TRUNC" }, \ -		{ O_DIRECT, "O_DIRECT" }) - -#define show_fmode_flags(mode) \ -	__print_flags(mode, "|", \ -		{ ((__force unsigned long)FMODE_READ), "READ" }, \ -		{ ((__force unsigned long)FMODE_WRITE), "WRITE" }, \ -		{ ((__force unsigned long)FMODE_EXEC), "EXEC" }) +#include <trace/events/fs.h> +#include <trace/events/nfs.h>  #define show_nfs_fattr_flags(valid) \  	__print_flags((unsigned long)valid, "|", \ @@ -365,7 +53,7 @@ DECLARE_EVENT_CLASS(nfs4_clientid_event,  		TP_printk(  			"error=%ld (%s) dstaddr=%s",  			-__entry->error, -			show_nfsv4_errors(__entry->error), +			show_nfs4_status(__entry->error),  			__get_str(dstaddr)  		)  ); @@ -389,29 +77,6 @@ DEFINE_NFS4_CLIENTID_EVENT(nfs4_bind_conn_to_session);  DEFINE_NFS4_CLIENTID_EVENT(nfs4_sequence);  DEFINE_NFS4_CLIENTID_EVENT(nfs4_reclaim_complete); -#define show_nfs4_sequence_status_flags(status) \ -	__print_flags((unsigned long)status, "|", \ -		{ SEQ4_STATUS_CB_PATH_DOWN, "CB_PATH_DOWN" }, \ -		{ SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRING, \ -			"CB_GSS_CONTEXTS_EXPIRING" }, \ -		{ SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRED, \ -			"CB_GSS_CONTEXTS_EXPIRED" }, \ -		{ SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED, \ -			"EXPIRED_ALL_STATE_REVOKED" }, \ -		{ SEQ4_STATUS_EXPIRED_SOME_STATE_REVOKED, \ -			"EXPIRED_SOME_STATE_REVOKED" }, \ -		{ SEQ4_STATUS_ADMIN_STATE_REVOKED, \ -			"ADMIN_STATE_REVOKED" }, \ -		{ SEQ4_STATUS_RECALLABLE_STATE_REVOKED,	 \ -			"RECALLABLE_STATE_REVOKED" }, \ -		{ SEQ4_STATUS_LEASE_MOVED, "LEASE_MOVED" }, \ -		{ SEQ4_STATUS_RESTART_RECLAIM_NEEDED, \ -			"RESTART_RECLAIM_NEEDED" }, \ -		{ SEQ4_STATUS_CB_PATH_DOWN_SESSION, \ -			"CB_PATH_DOWN_SESSION" }, \ -		{ SEQ4_STATUS_BACKCHANNEL_FAULT, \ -			"BACKCHANNEL_FAULT" }) -  TRACE_EVENT(nfs4_sequence_done,  		TP_PROTO(  			const struct nfs4_session *session, @@ -425,7 +90,7 @@ TRACE_EVENT(nfs4_sequence_done,  			__field(unsigned int, seq_nr)  			__field(unsigned int, highest_slotid)  			__field(unsigned int, target_highest_slotid) -			__field(unsigned int, status_flags) +			__field(unsigned long, status_flags)  			__field(unsigned long, error)  		), @@ -444,16 +109,16 @@ TRACE_EVENT(nfs4_sequence_done,  		TP_printk(  			"error=%ld (%s) session=0x%08x slot_nr=%u seq_nr=%u "  			"highest_slotid=%u target_highest_slotid=%u " -			"status_flags=%u (%s)", +			"status_flags=0x%lx (%s)",  			-__entry->error, -			show_nfsv4_errors(__entry->error), +			show_nfs4_status(__entry->error),  			__entry->session,  			__entry->slot_nr,  			__entry->seq_nr,  			__entry->highest_slotid,  			__entry->target_highest_slotid,  			__entry->status_flags, -			show_nfs4_sequence_status_flags(__entry->status_flags) +			show_nfs4_seq4_status(__entry->status_flags)  		)  ); @@ -490,7 +155,7 @@ TRACE_EVENT(nfs4_cb_sequence,  			"error=%ld (%s) session=0x%08x slot_nr=%u seq_nr=%u "  			"highest_slotid=%u",  			-__entry->error, -			show_nfsv4_errors(__entry->error), +			show_nfs4_status(__entry->error),  			__entry->session,  			__entry->slot_nr,  			__entry->seq_nr, @@ -527,7 +192,7 @@ TRACE_EVENT(nfs4_cb_seqid_err,  			"error=%ld (%s) session=0x%08x slot_nr=%u seq_nr=%u "  			"highest_slotid=%u",  			-__entry->error, -			show_nfsv4_errors(__entry->error), +			show_nfs4_status(__entry->error),  			__entry->session,  			__entry->slot_nr,  			__entry->seq_nr, @@ -535,6 +200,49 @@ TRACE_EVENT(nfs4_cb_seqid_err,  		)  ); +TRACE_EVENT(nfs4_cb_offload, +		TP_PROTO( +			const struct nfs_fh *cb_fh, +			const nfs4_stateid *cb_stateid, +			uint64_t cb_count, +			int cb_error, +			int cb_how_stable +		), + +		TP_ARGS(cb_fh, cb_stateid, cb_count, cb_error, +			cb_how_stable), + +		TP_STRUCT__entry( +			__field(unsigned long, error) +			__field(u32, fhandle) +			__field(loff_t, cb_count) +			__field(int, cb_how) +			__field(int, cb_stateid_seq) +			__field(u32, cb_stateid_hash) +		), + +		TP_fast_assign( +			__entry->error = cb_error < 0 ? -cb_error : 0; +			__entry->fhandle = nfs_fhandle_hash(cb_fh); +			__entry->cb_stateid_seq = +				be32_to_cpu(cb_stateid->seqid); +			__entry->cb_stateid_hash = +				nfs_stateid_hash(cb_stateid); +			__entry->cb_count = cb_count; +			__entry->cb_how = cb_how_stable; +		), + +		TP_printk( +			"error=%ld (%s) fhandle=0x%08x cb_stateid=%d:0x%08x " +			"cb_count=%llu cb_how=%s", +			-__entry->error, +			show_nfs4_status(__entry->error), +			__entry->fhandle, +			__entry->cb_stateid_seq, __entry->cb_stateid_hash, +			__entry->cb_count, +			show_nfs_stable_how(__entry->cb_how) +		) +);  #endif /* CONFIG_NFS_V4_1 */  TRACE_EVENT(nfs4_setup_sequence, @@ -661,7 +369,7 @@ TRACE_EVENT(nfs4_state_mgr_failed,  			"hostname=%s clp state=%s error=%ld (%s) section=%s",  			__get_str(hostname),  			show_nfs4_clp_state(__entry->state), -__entry->error, -			show_nfsv4_errors(__entry->error), __get_str(section) +			show_nfs4_status(__entry->error), __get_str(section)  		)  ) @@ -694,8 +402,8 @@ TRACE_EVENT(nfs4_xdr_bad_operation,  			__entry->expected = expected;  		), -		TP_printk( -			"task:%u@%d xid=0x%08x operation=%u, expected=%u", +		TP_printk(SUNRPC_TRACE_TASK_SPECIFIER +			  " xid=0x%08x operation=%u, expected=%u",  			__entry->task_id, __entry->client_id, __entry->xid,  			__entry->op, __entry->expected  		) @@ -729,10 +437,10 @@ DECLARE_EVENT_CLASS(nfs4_xdr_event,  			__entry->error = error;  		), -		TP_printk( -			"task:%u@%d xid=0x%08x error=%ld (%s) operation=%u", +		TP_printk(SUNRPC_TRACE_TASK_SPECIFIER +			  " xid=0x%08x error=%ld (%s) operation=%u",  			__entry->task_id, __entry->client_id, __entry->xid, -			-__entry->error, show_nfsv4_errors(__entry->error), +			-__entry->error, show_nfs4_status(__entry->error),  			__entry->op  		)  ); @@ -793,8 +501,8 @@ DECLARE_EVENT_CLASS(nfs4_open_event,  		TP_STRUCT__entry(  			__field(unsigned long, error) -			__field(unsigned int, flags) -			__field(unsigned int, fmode) +			__field(unsigned long, flags) +			__field(unsigned long, fmode)  			__field(dev_t, dev)  			__field(u32, fhandle)  			__field(u64, fileid) @@ -812,7 +520,7 @@ DECLARE_EVENT_CLASS(nfs4_open_event,  			__entry->error = -error;  			__entry->flags = flags; -			__entry->fmode = (__force unsigned int)ctx->mode; +			__entry->fmode = (__force unsigned long)ctx->mode;  			__entry->dev = ctx->dentry->d_sb->s_dev;  			if (!IS_ERR_OR_NULL(state)) {  				inode = state->inode; @@ -842,15 +550,15 @@ DECLARE_EVENT_CLASS(nfs4_open_event,  		),  		TP_printk( -			"error=%ld (%s) flags=%d (%s) fmode=%s " +			"error=%ld (%s) flags=%lu (%s) fmode=%s "  			"fileid=%02x:%02x:%llu fhandle=0x%08x "  			"name=%02x:%02x:%llu/%s stateid=%d:0x%08x "  			"openstateid=%d:0x%08x",  			 -__entry->error, -			 show_nfsv4_errors(__entry->error), +			 show_nfs4_status(__entry->error),  			 __entry->flags, -			 show_open_flags(__entry->flags), -			 show_fmode_flags(__entry->fmode), +			 show_fs_fcntl_open_flags(__entry->flags), +			 show_fs_fmode_flags(__entry->fmode),  			 MAJOR(__entry->dev), MINOR(__entry->dev),  			 (unsigned long long)__entry->fileid,  			 __entry->fhandle, @@ -904,7 +612,7 @@ TRACE_EVENT(nfs4_cached_open,  		TP_printk(  			"fmode=%s fileid=%02x:%02x:%llu "  			"fhandle=0x%08x stateid=%d:0x%08x", -			__entry->fmode ?  show_fmode_flags(__entry->fmode) : +			__entry->fmode ?  show_fs_fmode_flags(__entry->fmode) :  					  "closed",  			MAJOR(__entry->dev), MINOR(__entry->dev),  			(unsigned long long)__entry->fileid, @@ -951,8 +659,8 @@ TRACE_EVENT(nfs4_close,  			"error=%ld (%s) fmode=%s fileid=%02x:%02x:%llu "  			"fhandle=0x%08x openstateid=%d:0x%08x",  			-__entry->error, -			show_nfsv4_errors(__entry->error), -			__entry->fmode ?  show_fmode_flags(__entry->fmode) : +			show_nfs4_status(__entry->error), +			__entry->fmode ?  show_fs_fmode_flags(__entry->fmode) :  					  "closed",  			MAJOR(__entry->dev), MINOR(__entry->dev),  			(unsigned long long)__entry->fileid, @@ -961,24 +669,6 @@ TRACE_EVENT(nfs4_close,  		)  ); -TRACE_DEFINE_ENUM(F_GETLK); -TRACE_DEFINE_ENUM(F_SETLK); -TRACE_DEFINE_ENUM(F_SETLKW); -TRACE_DEFINE_ENUM(F_RDLCK); -TRACE_DEFINE_ENUM(F_WRLCK); -TRACE_DEFINE_ENUM(F_UNLCK); - -#define show_lock_cmd(type) \ -	__print_symbolic((int)type, \ -		{ F_GETLK, "GETLK" }, \ -		{ F_SETLK, "SETLK" }, \ -		{ F_SETLKW, "SETLKW" }) -#define show_lock_type(type) \ -	__print_symbolic((int)type, \ -		{ F_RDLCK, "RDLCK" }, \ -		{ F_WRLCK, "WRLCK" }, \ -		{ F_UNLCK, "UNLCK" }) -  DECLARE_EVENT_CLASS(nfs4_lock_event,  		TP_PROTO(  			const struct file_lock *request, @@ -991,8 +681,8 @@ DECLARE_EVENT_CLASS(nfs4_lock_event,  		TP_STRUCT__entry(  			__field(unsigned long, error) -			__field(int, cmd) -			__field(char, type) +			__field(unsigned long, cmd) +			__field(unsigned long, type)  			__field(loff_t, start)  			__field(loff_t, end)  			__field(dev_t, dev) @@ -1024,9 +714,9 @@ DECLARE_EVENT_CLASS(nfs4_lock_event,  			"fileid=%02x:%02x:%llu fhandle=0x%08x "  			"stateid=%d:0x%08x",  			-__entry->error, -			show_nfsv4_errors(__entry->error), -			show_lock_cmd(__entry->cmd), -			show_lock_type(__entry->type), +			show_nfs4_status(__entry->error), +			show_fs_fcntl_cmd(__entry->cmd), +			show_fs_fcntl_lock_type(__entry->type),  			(long long)__entry->start,  			(long long)__entry->end,  			MAJOR(__entry->dev), MINOR(__entry->dev), @@ -1061,8 +751,8 @@ TRACE_EVENT(nfs4_set_lock,  		TP_STRUCT__entry(  			__field(unsigned long, error) -			__field(int, cmd) -			__field(char, type) +			__field(unsigned long, cmd) +			__field(unsigned long, type)  			__field(loff_t, start)  			__field(loff_t, end)  			__field(dev_t, dev) @@ -1100,9 +790,9 @@ TRACE_EVENT(nfs4_set_lock,  			"fileid=%02x:%02x:%llu fhandle=0x%08x "  			"stateid=%d:0x%08x lockstateid=%d:0x%08x",  			-__entry->error, -			show_nfsv4_errors(__entry->error), -			show_lock_cmd(__entry->cmd), -			show_lock_type(__entry->type), +			show_nfs4_status(__entry->error), +			show_fs_fcntl_cmd(__entry->cmd), +			show_fs_fcntl_lock_type(__entry->type),  			(long long)__entry->start,  			(long long)__entry->end,  			MAJOR(__entry->dev), MINOR(__entry->dev), @@ -1219,7 +909,7 @@ DECLARE_EVENT_CLASS(nfs4_set_delegation_event,  		TP_printk(  			"fmode=%s fileid=%02x:%02x:%llu fhandle=0x%08x", -			show_fmode_flags(__entry->fmode), +			show_fs_fmode_flags(__entry->fmode),  			MAJOR(__entry->dev), MINOR(__entry->dev),  			(unsigned long long)__entry->fileid,  			__entry->fhandle @@ -1266,7 +956,7 @@ TRACE_EVENT(nfs4_delegreturn_exit,  			"error=%ld (%s) dev=%02x:%02x fhandle=0x%08x "  			"stateid=%d:0x%08x",  			-__entry->error, -			show_nfsv4_errors(__entry->error), +			show_nfs4_status(__entry->error),  			MAJOR(__entry->dev), MINOR(__entry->dev),  			__entry->fhandle,  			__entry->stateid_seq, __entry->stateid_hash @@ -1309,7 +999,7 @@ DECLARE_EVENT_CLASS(nfs4_test_stateid_event,  			"error=%ld (%s) fileid=%02x:%02x:%llu fhandle=0x%08x "  			"stateid=%d:0x%08x",  			-__entry->error, -			show_nfsv4_errors(__entry->error), +			show_nfs4_status(__entry->error),  			MAJOR(__entry->dev), MINOR(__entry->dev),  			(unsigned long long)__entry->fileid,  			__entry->fhandle, @@ -1356,7 +1046,7 @@ DECLARE_EVENT_CLASS(nfs4_lookup_event,  		TP_printk(  			"error=%ld (%s) name=%02x:%02x:%llu/%s",  			-__entry->error, -			show_nfsv4_errors(__entry->error), +			show_nfs4_status(__entry->error),  			MAJOR(__entry->dev), MINOR(__entry->dev),  			(unsigned long long)__entry->dir,  			__get_str(name) @@ -1403,7 +1093,7 @@ TRACE_EVENT(nfs4_lookupp,  		TP_printk(  			"error=%ld (%s) inode=%02x:%02x:%llu",  			-__entry->error, -			show_nfsv4_errors(__entry->error), +			show_nfs4_status(__entry->error),  			MAJOR(__entry->dev), MINOR(__entry->dev),  			(unsigned long long)__entry->ino  		) @@ -1442,7 +1132,7 @@ TRACE_EVENT(nfs4_rename,  			"error=%ld (%s) oldname=%02x:%02x:%llu/%s "  			"newname=%02x:%02x:%llu/%s",  			-__entry->error, -			show_nfsv4_errors(__entry->error), +			show_nfs4_status(__entry->error),  			MAJOR(__entry->dev), MINOR(__entry->dev),  			(unsigned long long)__entry->olddir,  			__get_str(oldname), @@ -1477,7 +1167,7 @@ DECLARE_EVENT_CLASS(nfs4_inode_event,  		TP_printk(  			"error=%ld (%s) fileid=%02x:%02x:%llu fhandle=0x%08x",  			-__entry->error, -			show_nfsv4_errors(__entry->error), +			show_nfs4_status(__entry->error),  			MAJOR(__entry->dev), MINOR(__entry->dev),  			(unsigned long long)__entry->fileid,  			__entry->fhandle @@ -1535,7 +1225,7 @@ DECLARE_EVENT_CLASS(nfs4_inode_stateid_event,  			"error=%ld (%s) fileid=%02x:%02x:%llu fhandle=0x%08x "  			"stateid=%d:0x%08x",  			-__entry->error, -			show_nfsv4_errors(__entry->error), +			show_nfs4_status(__entry->error),  			MAJOR(__entry->dev), MINOR(__entry->dev),  			(unsigned long long)__entry->fileid,  			__entry->fhandle, @@ -1588,7 +1278,7 @@ DECLARE_EVENT_CLASS(nfs4_getattr_event,  			"error=%ld (%s) fileid=%02x:%02x:%llu fhandle=0x%08x "  			"valid=%s",  			-__entry->error, -			show_nfsv4_errors(__entry->error), +			show_nfs4_status(__entry->error),  			MAJOR(__entry->dev), MINOR(__entry->dev),  			(unsigned long long)__entry->fileid,  			__entry->fhandle, @@ -1644,7 +1334,7 @@ DECLARE_EVENT_CLASS(nfs4_inode_callback_event,  			"error=%ld (%s) fileid=%02x:%02x:%llu fhandle=0x%08x "  			"dstaddr=%s",  			-__entry->error, -			show_nfsv4_errors(__entry->error), +			show_nfs4_status(__entry->error),  			MAJOR(__entry->dev), MINOR(__entry->dev),  			(unsigned long long)__entry->fileid,  			__entry->fhandle, @@ -1705,7 +1395,7 @@ DECLARE_EVENT_CLASS(nfs4_inode_stateid_callback_event,  			"error=%ld (%s) fileid=%02x:%02x:%llu fhandle=0x%08x "  			"stateid=%d:0x%08x dstaddr=%s",  			-__entry->error, -			show_nfsv4_errors(__entry->error), +			show_nfs4_status(__entry->error),  			MAJOR(__entry->dev), MINOR(__entry->dev),  			(unsigned long long)__entry->fileid,  			__entry->fhandle, @@ -1754,7 +1444,7 @@ DECLARE_EVENT_CLASS(nfs4_idmap_event,  		TP_printk(  			"error=%ld (%s) id=%u name=%s", -			-__entry->error, show_nfsv4_errors(__entry->error), +			-__entry->error, show_nfs4_status(__entry->error),  			__entry->id,  			__get_str(name)  		) @@ -1832,7 +1522,7 @@ DECLARE_EVENT_CLASS(nfs4_read_event,  			"offset=%lld count=%u res=%u stateid=%d:0x%08x "  			"layoutstateid=%d:0x%08x",  			-__entry->error, -			show_nfsv4_errors(__entry->error), +			show_nfs4_status(__entry->error),  			MAJOR(__entry->dev), MINOR(__entry->dev),  			(unsigned long long)__entry->fileid,  			__entry->fhandle, @@ -1906,7 +1596,7 @@ DECLARE_EVENT_CLASS(nfs4_write_event,  			"offset=%lld count=%u res=%u stateid=%d:0x%08x "  			"layoutstateid=%d:0x%08x",  			-__entry->error, -			show_nfsv4_errors(__entry->error), +			show_nfs4_status(__entry->error),  			MAJOR(__entry->dev), MINOR(__entry->dev),  			(unsigned long long)__entry->fileid,  			__entry->fhandle, @@ -1970,7 +1660,7 @@ DECLARE_EVENT_CLASS(nfs4_commit_event,  			"error=%ld (%s) fileid=%02x:%02x:%llu fhandle=0x%08x "  			"offset=%lld count=%u layoutstateid=%d:0x%08x",  			-__entry->error, -			show_nfsv4_errors(__entry->error), +			show_nfs4_status(__entry->error),  			MAJOR(__entry->dev), MINOR(__entry->dev),  			(unsigned long long)__entry->fileid,  			__entry->fhandle, @@ -1990,16 +1680,6 @@ DEFINE_NFS4_COMMIT_EVENT(nfs4_commit);  #ifdef CONFIG_NFS_V4_1  DEFINE_NFS4_COMMIT_EVENT(nfs4_pnfs_commit_ds); -TRACE_DEFINE_ENUM(IOMODE_READ); -TRACE_DEFINE_ENUM(IOMODE_RW); -TRACE_DEFINE_ENUM(IOMODE_ANY); - -#define show_pnfs_iomode(iomode) \ -	__print_symbolic(iomode, \ -		{ IOMODE_READ, "READ" }, \ -		{ IOMODE_RW, "RW" }, \ -		{ IOMODE_ANY, "ANY" }) -  TRACE_EVENT(nfs4_layoutget,  		TP_PROTO(  			const struct nfs_open_context *ctx, @@ -2055,11 +1735,11 @@ TRACE_EVENT(nfs4_layoutget,  			"iomode=%s offset=%llu count=%llu stateid=%d:0x%08x "  			"layoutstateid=%d:0x%08x",  			-__entry->error, -			show_nfsv4_errors(__entry->error), +			show_nfs4_status(__entry->error),  			MAJOR(__entry->dev), MINOR(__entry->dev),  			(unsigned long long)__entry->fileid,  			__entry->fhandle, -			show_pnfs_iomode(__entry->iomode), +			show_pnfs_layout_iomode(__entry->iomode),  			(unsigned long long)__entry->offset,  			(unsigned long long)__entry->count,  			__entry->stateid_seq, __entry->stateid_hash, @@ -2153,7 +1833,7 @@ TRACE_EVENT(pnfs_update_layout,  			MAJOR(__entry->dev), MINOR(__entry->dev),  			(unsigned long long)__entry->fileid,  			__entry->fhandle, -			show_pnfs_iomode(__entry->iomode), +			show_pnfs_layout_iomode(__entry->iomode),  			(unsigned long long)__entry->pos,  			(unsigned long long)__entry->count,  			__entry->layoutstateid_seq, __entry->layoutstateid_hash, @@ -2207,7 +1887,7 @@ DECLARE_EVENT_CLASS(pnfs_layout_event,  			MAJOR(__entry->dev), MINOR(__entry->dev),  			(unsigned long long)__entry->fileid,  			__entry->fhandle, -			show_pnfs_iomode(__entry->iomode), +			show_pnfs_layout_iomode(__entry->iomode),  			(unsigned long long)__entry->pos,  			(unsigned long long)__entry->count,  			__entry->layoutstateid_seq, __entry->layoutstateid_hash, @@ -2352,7 +2032,7 @@ DECLARE_EVENT_CLASS(nfs4_flexfiles_io_event,  			"error=%ld (%s) fileid=%02x:%02x:%llu fhandle=0x%08x "  			"offset=%llu count=%u stateid=%d:0x%08x dstaddr=%s",  			-__entry->error, -			show_nfsv4_errors(__entry->error), +			show_nfs4_status(__entry->error),  			MAJOR(__entry->dev), MINOR(__entry->dev),  			(unsigned long long)__entry->fileid,  			__entry->fhandle, @@ -2408,7 +2088,7 @@ TRACE_EVENT(ff_layout_commit_error,  			"error=%ld (%s) fileid=%02x:%02x:%llu fhandle=0x%08x "  			"offset=%llu count=%u dstaddr=%s",  			-__entry->error, -			show_nfsv4_errors(__entry->error), +			show_nfs4_status(__entry->error),  			MAJOR(__entry->dev), MINOR(__entry->dev),  			(unsigned long long)__entry->fileid,  			__entry->fhandle, @@ -2417,6 +2097,406 @@ TRACE_EVENT(ff_layout_commit_error,  		)  ); +TRACE_DEFINE_ENUM(NFS4_CONTENT_DATA); +TRACE_DEFINE_ENUM(NFS4_CONTENT_HOLE); + +#define show_llseek_mode(what)			\ +	__print_symbolic(what,			\ +		{ NFS4_CONTENT_DATA, "DATA" },		\ +		{ NFS4_CONTENT_HOLE, "HOLE" }) + +#ifdef CONFIG_NFS_V4_2 +TRACE_EVENT(nfs4_llseek, +		TP_PROTO( +			const struct inode *inode, +			const struct nfs42_seek_args *args, +			const struct nfs42_seek_res *res, +			int error +		), + +		TP_ARGS(inode, args, res, error), + +		TP_STRUCT__entry( +			__field(unsigned long, error) +			__field(u32, fhandle) +			__field(u32, fileid) +			__field(dev_t, dev) +			__field(int, stateid_seq) +			__field(u32, stateid_hash) +			__field(loff_t, offset_s) +			__field(u32, what) +			__field(loff_t, offset_r) +			__field(u32, eof) +		), + +		TP_fast_assign( +			const struct nfs_inode *nfsi = NFS_I(inode); +			const struct nfs_fh *fh = args->sa_fh; + +			__entry->fileid = nfsi->fileid; +			__entry->dev = inode->i_sb->s_dev; +			__entry->fhandle = nfs_fhandle_hash(fh); +			__entry->offset_s = args->sa_offset; +			__entry->stateid_seq = +				be32_to_cpu(args->sa_stateid.seqid); +			__entry->stateid_hash = +				nfs_stateid_hash(&args->sa_stateid); +			__entry->what = args->sa_what; +			if (error) { +				__entry->error = -error; +				__entry->offset_r = 0; +				__entry->eof = 0; +			} else { +				__entry->error = 0; +				__entry->offset_r = res->sr_offset; +				__entry->eof = res->sr_eof; +			} +		), + +		TP_printk( +			"error=%ld (%s) fileid=%02x:%02x:%llu fhandle=0x%08x " +			"stateid=%d:0x%08x offset_s=%llu what=%s " +			"offset_r=%llu eof=%u", +			-__entry->error, +			show_nfs4_status(__entry->error), +			MAJOR(__entry->dev), MINOR(__entry->dev), +			(unsigned long long)__entry->fileid, +			__entry->fhandle, +			__entry->stateid_seq, __entry->stateid_hash, +			__entry->offset_s, +			show_llseek_mode(__entry->what), +			__entry->offset_r, +			__entry->eof +		) +); + +DECLARE_EVENT_CLASS(nfs4_sparse_event, +		TP_PROTO( +			const struct inode *inode, +			const struct nfs42_falloc_args *args, +			int error +		), + +		TP_ARGS(inode, args, error), + +		TP_STRUCT__entry( +			__field(unsigned long, error) +			__field(loff_t, offset) +			__field(loff_t, len) +			__field(dev_t, dev) +			__field(u32, fhandle) +			__field(u64, fileid) +			__field(int, stateid_seq) +			__field(u32, stateid_hash) +		), + +		TP_fast_assign( +			__entry->error = error < 0 ? -error : 0; +			__entry->offset = args->falloc_offset; +			__entry->len = args->falloc_length; +			__entry->dev = inode->i_sb->s_dev; +			__entry->fileid = NFS_FILEID(inode); +			__entry->fhandle = nfs_fhandle_hash(NFS_FH(inode)); +			__entry->stateid_seq = +				be32_to_cpu(args->falloc_stateid.seqid); +			__entry->stateid_hash = +				nfs_stateid_hash(&args->falloc_stateid); +		), + +		TP_printk( +			"error=%ld (%s) fileid=%02x:%02x:%llu fhandle=0x%08x " +			"stateid=%d:0x%08x offset=%llu len=%llu", +			-__entry->error, +			show_nfs4_status(__entry->error), +			MAJOR(__entry->dev), MINOR(__entry->dev), +			(unsigned long long)__entry->fileid, +			__entry->fhandle, +			__entry->stateid_seq, __entry->stateid_hash, +			(long long)__entry->offset, +			(long long)__entry->len +		) +); +#define DEFINE_NFS4_SPARSE_EVENT(name) \ +	DEFINE_EVENT(nfs4_sparse_event, name, \ +			TP_PROTO( \ +				const struct inode *inode, \ +				const struct nfs42_falloc_args *args, \ +				int error \ +			), \ +			TP_ARGS(inode, args, error)) +DEFINE_NFS4_SPARSE_EVENT(nfs4_fallocate); +DEFINE_NFS4_SPARSE_EVENT(nfs4_deallocate); + +TRACE_EVENT(nfs4_copy, +		TP_PROTO( +			const struct inode *src_inode, +			const struct inode *dst_inode, +			const struct nfs42_copy_args *args, +			const struct nfs42_copy_res *res, +			const struct nl4_server *nss, +			int error +		), + +		TP_ARGS(src_inode, dst_inode, args, res, nss, error), + +		TP_STRUCT__entry( +			__field(unsigned long, error) +			__field(u32, src_fhandle) +			__field(u32, src_fileid) +			__field(u32, dst_fhandle) +			__field(u32, dst_fileid) +			__field(dev_t, src_dev) +			__field(dev_t, dst_dev) +			__field(int, src_stateid_seq) +			__field(u32, src_stateid_hash) +			__field(int, dst_stateid_seq) +			__field(u32, dst_stateid_hash) +			__field(loff_t, src_offset) +			__field(loff_t, dst_offset) +			__field(bool, sync) +			__field(loff_t, len) +			__field(int, res_stateid_seq) +			__field(u32, res_stateid_hash) +			__field(loff_t, res_count) +			__field(bool, res_sync) +			__field(bool, res_cons) +			__field(bool, intra) +		), + +		TP_fast_assign( +			const struct nfs_inode *src_nfsi = NFS_I(src_inode); +			const struct nfs_inode *dst_nfsi = NFS_I(dst_inode); + +			__entry->src_fileid = src_nfsi->fileid; +			__entry->src_dev = src_inode->i_sb->s_dev; +			__entry->src_fhandle = nfs_fhandle_hash(args->src_fh); +			__entry->src_offset = args->src_pos; +			__entry->dst_fileid = dst_nfsi->fileid; +			__entry->dst_dev = dst_inode->i_sb->s_dev; +			__entry->dst_fhandle = nfs_fhandle_hash(args->dst_fh); +			__entry->dst_offset = args->dst_pos; +			__entry->len = args->count; +			__entry->sync = args->sync; +			__entry->src_stateid_seq = +				be32_to_cpu(args->src_stateid.seqid); +			__entry->src_stateid_hash = +				nfs_stateid_hash(&args->src_stateid); +			__entry->dst_stateid_seq = +				be32_to_cpu(args->dst_stateid.seqid); +			__entry->dst_stateid_hash = +				nfs_stateid_hash(&args->dst_stateid); +			__entry->intra = nss ? 0 : 1; +			if (error) { +				__entry->error = -error; +				__entry->res_stateid_seq = 0; +				__entry->res_stateid_hash = 0; +				__entry->res_count = 0; +				__entry->res_sync = 0; +				__entry->res_cons = 0; +			} else { +				__entry->error = 0; +				__entry->res_stateid_seq = +					be32_to_cpu(res->write_res.stateid.seqid); +				__entry->res_stateid_hash = +					nfs_stateid_hash(&res->write_res.stateid); +				__entry->res_count = res->write_res.count; +				__entry->res_sync = res->synchronous; +				__entry->res_cons = res->consecutive; +			} +		), + +		TP_printk( +			"error=%ld (%s) intra=%d src_fileid=%02x:%02x:%llu " +			"src_fhandle=0x%08x dst_fileid=%02x:%02x:%llu " +			"dst_fhandle=0x%08x src_stateid=%d:0x%08x " +			"dst_stateid=%d:0x%08x src_offset=%llu dst_offset=%llu " +			"len=%llu sync=%d cb_stateid=%d:0x%08x res_sync=%d " +			"res_cons=%d res_count=%llu", +			-__entry->error, +			show_nfs4_status(__entry->error), +			__entry->intra, +			MAJOR(__entry->src_dev), MINOR(__entry->src_dev), +			(unsigned long long)__entry->src_fileid, +			__entry->src_fhandle, +			MAJOR(__entry->dst_dev), MINOR(__entry->dst_dev), +			(unsigned long long)__entry->dst_fileid, +			__entry->dst_fhandle, +			__entry->src_stateid_seq, __entry->src_stateid_hash, +			__entry->dst_stateid_seq, __entry->dst_stateid_hash, +			__entry->src_offset, +			__entry->dst_offset, +			__entry->len, +			__entry->sync, +			__entry->res_stateid_seq, __entry->res_stateid_hash, +			__entry->res_sync, +			__entry->res_cons, +			__entry->res_count +		) +); + +TRACE_EVENT(nfs4_clone, +		TP_PROTO( +			const struct inode *src_inode, +			const struct inode *dst_inode, +			const struct nfs42_clone_args *args, +			int error +		), + +		TP_ARGS(src_inode, dst_inode, args, error), + +		TP_STRUCT__entry( +			__field(unsigned long, error) +			__field(u32, src_fhandle) +			__field(u32, src_fileid) +			__field(u32, dst_fhandle) +			__field(u32, dst_fileid) +			__field(dev_t, src_dev) +			__field(dev_t, dst_dev) +			__field(loff_t, src_offset) +			__field(loff_t, dst_offset) +			__field(int, src_stateid_seq) +			__field(u32, src_stateid_hash) +			__field(int, dst_stateid_seq) +			__field(u32, dst_stateid_hash) +			__field(loff_t, len) +		), + +		TP_fast_assign( +			const struct nfs_inode *src_nfsi = NFS_I(src_inode); +			const struct nfs_inode *dst_nfsi = NFS_I(dst_inode); + +			__entry->src_fileid = src_nfsi->fileid; +			__entry->src_dev = src_inode->i_sb->s_dev; +			__entry->src_fhandle = nfs_fhandle_hash(args->src_fh); +			__entry->src_offset = args->src_offset; +			__entry->dst_fileid = dst_nfsi->fileid; +			__entry->dst_dev = dst_inode->i_sb->s_dev; +			__entry->dst_fhandle = nfs_fhandle_hash(args->dst_fh); +			__entry->dst_offset = args->dst_offset; +			__entry->len = args->count; +			__entry->error = error < 0 ? -error : 0; +			__entry->src_stateid_seq = +				be32_to_cpu(args->src_stateid.seqid); +			__entry->src_stateid_hash = +				nfs_stateid_hash(&args->src_stateid); +			__entry->dst_stateid_seq = +				be32_to_cpu(args->dst_stateid.seqid); +			__entry->dst_stateid_hash = +				nfs_stateid_hash(&args->dst_stateid); +		), + +		TP_printk( +			"error=%ld (%s) src_fileid=%02x:%02x:%llu " +			"src_fhandle=0x%08x dst_fileid=%02x:%02x:%llu " +			"dst_fhandle=0x%08x src_stateid=%d:0x%08x " +			"dst_stateid=%d:0x%08x src_offset=%llu " +			"dst_offset=%llu len=%llu", +			-__entry->error, +			show_nfs4_status(__entry->error), +			MAJOR(__entry->src_dev), MINOR(__entry->src_dev), +			(unsigned long long)__entry->src_fileid, +			__entry->src_fhandle, +			MAJOR(__entry->dst_dev), MINOR(__entry->dst_dev), +			(unsigned long long)__entry->dst_fileid, +			__entry->dst_fhandle, +			__entry->src_stateid_seq, __entry->src_stateid_hash, +			__entry->dst_stateid_seq, __entry->dst_stateid_hash, +			__entry->src_offset, +			__entry->dst_offset, +			__entry->len +		) +); + +TRACE_EVENT(nfs4_copy_notify, +		TP_PROTO( +			const struct inode *inode, +			const struct nfs42_copy_notify_args *args, +			const struct nfs42_copy_notify_res *res, +			int error +		), + +		TP_ARGS(inode, args, res, error), + +		TP_STRUCT__entry( +			__field(unsigned long, error) +			__field(u32, fhandle) +			__field(u32, fileid) +			__field(dev_t, dev) +			__field(int, stateid_seq) +			__field(u32, stateid_hash) +			__field(int, res_stateid_seq) +			__field(u32, res_stateid_hash) +		), + +		TP_fast_assign( +			const struct nfs_inode *nfsi = NFS_I(inode); + +			__entry->fileid = nfsi->fileid; +			__entry->dev = inode->i_sb->s_dev; +			__entry->fhandle = nfs_fhandle_hash(args->cna_src_fh); +			__entry->stateid_seq = +				be32_to_cpu(args->cna_src_stateid.seqid); +			__entry->stateid_hash = +				nfs_stateid_hash(&args->cna_src_stateid); +			if (error) { +				__entry->error = -error; +				__entry->res_stateid_seq = 0; +				__entry->res_stateid_hash = 0; +			} else { +				__entry->error = 0; +				__entry->res_stateid_seq = +					be32_to_cpu(res->cnr_stateid.seqid); +				__entry->res_stateid_hash = +					nfs_stateid_hash(&res->cnr_stateid); +			} +		), + +		TP_printk( +			"error=%ld (%s) fileid=%02x:%02x:%llu fhandle=0x%08x " +			"stateid=%d:0x%08x res_stateid=%d:0x%08x", +			-__entry->error, +			show_nfs4_status(__entry->error), +			MAJOR(__entry->dev), MINOR(__entry->dev), +			(unsigned long long)__entry->fileid, +			__entry->fhandle, +			__entry->stateid_seq, __entry->stateid_hash, +			__entry->res_stateid_seq, __entry->res_stateid_hash +		) +); + +TRACE_EVENT(nfs4_offload_cancel, +		TP_PROTO( +			const struct nfs42_offload_status_args *args, +			int error +		), + +		TP_ARGS(args, error), + +		TP_STRUCT__entry( +			__field(unsigned long, error) +			__field(u32, fhandle) +			__field(int, stateid_seq) +			__field(u32, stateid_hash) +		), + +		TP_fast_assign( +			__entry->fhandle = nfs_fhandle_hash(args->osa_src_fh); +			__entry->error = error < 0 ? -error : 0; +			__entry->stateid_seq = +				be32_to_cpu(args->osa_stateid.seqid); +			__entry->stateid_hash = +				nfs_stateid_hash(&args->osa_stateid); +		), + +		TP_printk( +			"error=%ld (%s) fhandle=0x%08x stateid=%d:0x%08x", +			-__entry->error, +			show_nfs4_status(__entry->error), +			__entry->fhandle, +			__entry->stateid_seq, __entry->stateid_hash +		) +); +#endif /* CONFIG_NFS_V4_2 */  #endif /* CONFIG_NFS_V4_1 */ diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index a8cff19c6f00..69862bf6db00 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -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 @@ xdr_error:  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 @@ xdr_error:  	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; diff --git a/fs/nfs/nfstrace.h b/fs/nfs/nfstrace.h index 8a224871be74..21dac847f1e4 100644 --- a/fs/nfs/nfstrace.h +++ b/fs/nfs/nfstrace.h @@ -11,45 +11,9 @@  #include <linux/tracepoint.h>  #include <linux/iversion.h> -TRACE_DEFINE_ENUM(DT_UNKNOWN); -TRACE_DEFINE_ENUM(DT_FIFO); -TRACE_DEFINE_ENUM(DT_CHR); -TRACE_DEFINE_ENUM(DT_DIR); -TRACE_DEFINE_ENUM(DT_BLK); -TRACE_DEFINE_ENUM(DT_REG); -TRACE_DEFINE_ENUM(DT_LNK); -TRACE_DEFINE_ENUM(DT_SOCK); -TRACE_DEFINE_ENUM(DT_WHT); - -#define nfs_show_file_type(ftype) \ -	__print_symbolic(ftype, \ -			{ DT_UNKNOWN, "UNKNOWN" }, \ -			{ DT_FIFO, "FIFO" }, \ -			{ DT_CHR, "CHR" }, \ -			{ DT_DIR, "DIR" }, \ -			{ DT_BLK, "BLK" }, \ -			{ DT_REG, "REG" }, \ -			{ DT_LNK, "LNK" }, \ -			{ DT_SOCK, "SOCK" }, \ -			{ DT_WHT, "WHT" }) - -TRACE_DEFINE_ENUM(NFS_INO_INVALID_DATA); -TRACE_DEFINE_ENUM(NFS_INO_INVALID_ATIME); -TRACE_DEFINE_ENUM(NFS_INO_INVALID_ACCESS); -TRACE_DEFINE_ENUM(NFS_INO_INVALID_ACL); -TRACE_DEFINE_ENUM(NFS_INO_REVAL_PAGECACHE); -TRACE_DEFINE_ENUM(NFS_INO_REVAL_FORCED); -TRACE_DEFINE_ENUM(NFS_INO_INVALID_LABEL); -TRACE_DEFINE_ENUM(NFS_INO_INVALID_CHANGE); -TRACE_DEFINE_ENUM(NFS_INO_INVALID_CTIME); -TRACE_DEFINE_ENUM(NFS_INO_INVALID_MTIME); -TRACE_DEFINE_ENUM(NFS_INO_INVALID_SIZE); -TRACE_DEFINE_ENUM(NFS_INO_INVALID_OTHER); -TRACE_DEFINE_ENUM(NFS_INO_DATA_INVAL_DEFER); -TRACE_DEFINE_ENUM(NFS_INO_INVALID_BLOCKS); -TRACE_DEFINE_ENUM(NFS_INO_INVALID_XATTR); -TRACE_DEFINE_ENUM(NFS_INO_INVALID_NLINK); -TRACE_DEFINE_ENUM(NFS_INO_INVALID_MODE); +#include <trace/events/fs.h> +#include <trace/events/nfs.h> +#include <trace/events/sunrpc_base.h>  #define nfs_show_cache_validity(v) \  	__print_flags(v, "|", \ @@ -71,17 +35,6 @@ TRACE_DEFINE_ENUM(NFS_INO_INVALID_MODE);  			{ NFS_INO_INVALID_NLINK, "INVALID_NLINK" }, \  			{ NFS_INO_INVALID_MODE, "INVALID_MODE" }) -TRACE_DEFINE_ENUM(NFS_INO_ADVISE_RDPLUS); -TRACE_DEFINE_ENUM(NFS_INO_STALE); -TRACE_DEFINE_ENUM(NFS_INO_ACL_LRU_SET); -TRACE_DEFINE_ENUM(NFS_INO_INVALIDATING); -TRACE_DEFINE_ENUM(NFS_INO_FSCACHE); -TRACE_DEFINE_ENUM(NFS_INO_FSCACHE_LOCK); -TRACE_DEFINE_ENUM(NFS_INO_LAYOUTCOMMIT); -TRACE_DEFINE_ENUM(NFS_INO_LAYOUTCOMMITTING); -TRACE_DEFINE_ENUM(NFS_INO_LAYOUTSTATS); -TRACE_DEFINE_ENUM(NFS_INO_ODIRECT); -  #define nfs_show_nfsi_flags(v) \  	__print_flags(v, "|", \  			{ BIT(NFS_INO_ADVISE_RDPLUS), "ADVISE_RDPLUS" }, \ @@ -163,12 +116,12 @@ DECLARE_EVENT_CLASS(nfs_inode_event_done,  			"error=%ld (%s) fileid=%02x:%02x:%llu fhandle=0x%08x "  			"type=%u (%s) version=%llu size=%lld "  			"cache_validity=0x%lx (%s) nfs_flags=0x%lx (%s)", -			-__entry->error, nfs_show_status(__entry->error), +			-__entry->error, show_nfs_status(__entry->error),  			MAJOR(__entry->dev), MINOR(__entry->dev),  			(unsigned long long)__entry->fileid,  			__entry->fhandle,  			__entry->type, -			nfs_show_file_type(__entry->type), +			show_fs_dirent_type(__entry->type),  			(unsigned long long)__entry->version,  			(long long)__entry->size,  			__entry->cache_validity, @@ -254,12 +207,12 @@ TRACE_EVENT(nfs_access_exit,  			"type=%u (%s) version=%llu size=%lld "  			"cache_validity=0x%lx (%s) nfs_flags=0x%lx (%s) "  			"mask=0x%x permitted=0x%x", -			-__entry->error, nfs_show_status(__entry->error), +			-__entry->error, show_nfs_status(__entry->error),  			MAJOR(__entry->dev), MINOR(__entry->dev),  			(unsigned long long)__entry->fileid,  			__entry->fhandle,  			__entry->type, -			nfs_show_file_type(__entry->type), +			show_fs_dirent_type(__entry->type),  			(unsigned long long)__entry->version,  			(long long)__entry->size,  			__entry->cache_validity, @@ -270,33 +223,55 @@ TRACE_EVENT(nfs_access_exit,  		)  ); -TRACE_DEFINE_ENUM(LOOKUP_FOLLOW); -TRACE_DEFINE_ENUM(LOOKUP_DIRECTORY); -TRACE_DEFINE_ENUM(LOOKUP_AUTOMOUNT); -TRACE_DEFINE_ENUM(LOOKUP_PARENT); -TRACE_DEFINE_ENUM(LOOKUP_REVAL); -TRACE_DEFINE_ENUM(LOOKUP_RCU); -TRACE_DEFINE_ENUM(LOOKUP_OPEN); -TRACE_DEFINE_ENUM(LOOKUP_CREATE); -TRACE_DEFINE_ENUM(LOOKUP_EXCL); -TRACE_DEFINE_ENUM(LOOKUP_RENAME_TARGET); -TRACE_DEFINE_ENUM(LOOKUP_EMPTY); -TRACE_DEFINE_ENUM(LOOKUP_DOWN); - -#define show_lookup_flags(flags) \ -	__print_flags(flags, "|", \ -			{ LOOKUP_FOLLOW, "FOLLOW" }, \ -			{ LOOKUP_DIRECTORY, "DIRECTORY" }, \ -			{ LOOKUP_AUTOMOUNT, "AUTOMOUNT" }, \ -			{ LOOKUP_PARENT, "PARENT" }, \ -			{ LOOKUP_REVAL, "REVAL" }, \ -			{ LOOKUP_RCU, "RCU" }, \ -			{ LOOKUP_OPEN, "OPEN" }, \ -			{ LOOKUP_CREATE, "CREATE" }, \ -			{ LOOKUP_EXCL, "EXCL" }, \ -			{ LOOKUP_RENAME_TARGET, "RENAME_TARGET" }, \ -			{ LOOKUP_EMPTY, "EMPTY" }, \ -			{ LOOKUP_DOWN, "DOWN" }) +DECLARE_EVENT_CLASS(nfs_update_size_class, +		TP_PROTO( +			const struct inode *inode, +			loff_t new_size +		), + +		TP_ARGS(inode, new_size), + +		TP_STRUCT__entry( +			__field(dev_t, dev) +			__field(u32, fhandle) +			__field(u64, fileid) +			__field(u64, version) +			__field(loff_t, cur_size) +			__field(loff_t, new_size) +		), + +		TP_fast_assign( +			const struct nfs_inode *nfsi = NFS_I(inode); + +			__entry->dev = inode->i_sb->s_dev; +			__entry->fhandle = nfs_fhandle_hash(&nfsi->fh); +			__entry->fileid = nfsi->fileid; +			__entry->version = inode_peek_iversion_raw(inode); +			__entry->cur_size = i_size_read(inode); +			__entry->new_size = new_size; +		), + +		TP_printk( +			"fileid=%02x:%02x:%llu fhandle=0x%08x version=%llu cursize=%lld newsize=%lld", +			MAJOR(__entry->dev), MINOR(__entry->dev), +			(unsigned long long)__entry->fileid, +			__entry->fhandle, __entry->version, +			__entry->cur_size, __entry->new_size +		) +); + +#define DEFINE_NFS_UPDATE_SIZE_EVENT(name) \ +	DEFINE_EVENT(nfs_update_size_class, nfs_size_##name, \ +			TP_PROTO( \ +				const struct inode *inode, \ +				loff_t new_size \ +			), \ +			TP_ARGS(inode, new_size)) + +DEFINE_NFS_UPDATE_SIZE_EVENT(truncate); +DEFINE_NFS_UPDATE_SIZE_EVENT(wcc); +DEFINE_NFS_UPDATE_SIZE_EVENT(update); +DEFINE_NFS_UPDATE_SIZE_EVENT(grow);  DECLARE_EVENT_CLASS(nfs_lookup_event,  		TP_PROTO( @@ -324,7 +299,7 @@ DECLARE_EVENT_CLASS(nfs_lookup_event,  		TP_printk(  			"flags=0x%lx (%s) name=%02x:%02x:%llu/%s",  			__entry->flags, -			show_lookup_flags(__entry->flags), +			show_fs_lookup_flags(__entry->flags),  			MAJOR(__entry->dev), MINOR(__entry->dev),  			(unsigned long long)__entry->dir,  			__get_str(name) @@ -368,9 +343,9 @@ DECLARE_EVENT_CLASS(nfs_lookup_event_done,  		TP_printk(  			"error=%ld (%s) flags=0x%lx (%s) name=%02x:%02x:%llu/%s", -			-__entry->error, nfs_show_status(__entry->error), +			-__entry->error, show_nfs_status(__entry->error),  			__entry->flags, -			show_lookup_flags(__entry->flags), +			show_fs_lookup_flags(__entry->flags),  			MAJOR(__entry->dev), MINOR(__entry->dev),  			(unsigned long long)__entry->dir,  			__get_str(name) @@ -392,46 +367,6 @@ DEFINE_NFS_LOOKUP_EVENT_DONE(nfs_lookup_exit);  DEFINE_NFS_LOOKUP_EVENT(nfs_lookup_revalidate_enter);  DEFINE_NFS_LOOKUP_EVENT_DONE(nfs_lookup_revalidate_exit); -TRACE_DEFINE_ENUM(O_WRONLY); -TRACE_DEFINE_ENUM(O_RDWR); -TRACE_DEFINE_ENUM(O_CREAT); -TRACE_DEFINE_ENUM(O_EXCL); -TRACE_DEFINE_ENUM(O_NOCTTY); -TRACE_DEFINE_ENUM(O_TRUNC); -TRACE_DEFINE_ENUM(O_APPEND); -TRACE_DEFINE_ENUM(O_NONBLOCK); -TRACE_DEFINE_ENUM(O_DSYNC); -TRACE_DEFINE_ENUM(O_DIRECT); -TRACE_DEFINE_ENUM(O_LARGEFILE); -TRACE_DEFINE_ENUM(O_DIRECTORY); -TRACE_DEFINE_ENUM(O_NOFOLLOW); -TRACE_DEFINE_ENUM(O_NOATIME); -TRACE_DEFINE_ENUM(O_CLOEXEC); - -#define show_open_flags(flags) \ -	__print_flags(flags, "|", \ -		{ O_WRONLY, "O_WRONLY" }, \ -		{ O_RDWR, "O_RDWR" }, \ -		{ O_CREAT, "O_CREAT" }, \ -		{ O_EXCL, "O_EXCL" }, \ -		{ O_NOCTTY, "O_NOCTTY" }, \ -		{ O_TRUNC, "O_TRUNC" }, \ -		{ O_APPEND, "O_APPEND" }, \ -		{ O_NONBLOCK, "O_NONBLOCK" }, \ -		{ O_DSYNC, "O_DSYNC" }, \ -		{ O_DIRECT, "O_DIRECT" }, \ -		{ O_LARGEFILE, "O_LARGEFILE" }, \ -		{ O_DIRECTORY, "O_DIRECTORY" }, \ -		{ O_NOFOLLOW, "O_NOFOLLOW" }, \ -		{ O_NOATIME, "O_NOATIME" }, \ -		{ O_CLOEXEC, "O_CLOEXEC" }) - -#define show_fmode_flags(mode) \ -	__print_flags(mode, "|", \ -		{ ((__force unsigned long)FMODE_READ), "READ" }, \ -		{ ((__force unsigned long)FMODE_WRITE), "WRITE" }, \ -		{ ((__force unsigned long)FMODE_EXEC), "EXEC" }) -  TRACE_EVENT(nfs_atomic_open_enter,  		TP_PROTO(  			const struct inode *dir, @@ -443,7 +378,7 @@ TRACE_EVENT(nfs_atomic_open_enter,  		TP_STRUCT__entry(  			__field(unsigned long, flags) -			__field(unsigned int, fmode) +			__field(unsigned long, fmode)  			__field(dev_t, dev)  			__field(u64, dir)  			__string(name, ctx->dentry->d_name.name) @@ -453,15 +388,15 @@ TRACE_EVENT(nfs_atomic_open_enter,  			__entry->dev = dir->i_sb->s_dev;  			__entry->dir = NFS_FILEID(dir);  			__entry->flags = flags; -			__entry->fmode = (__force unsigned int)ctx->mode; +			__entry->fmode = (__force unsigned long)ctx->mode;  			__assign_str(name, ctx->dentry->d_name.name);  		),  		TP_printk(  			"flags=0x%lx (%s) fmode=%s name=%02x:%02x:%llu/%s",  			__entry->flags, -			show_open_flags(__entry->flags), -			show_fmode_flags(__entry->fmode), +			show_fs_fcntl_open_flags(__entry->flags), +			show_fs_fmode_flags(__entry->fmode),  			MAJOR(__entry->dev), MINOR(__entry->dev),  			(unsigned long long)__entry->dir,  			__get_str(name) @@ -481,7 +416,7 @@ TRACE_EVENT(nfs_atomic_open_exit,  		TP_STRUCT__entry(  			__field(unsigned long, error)  			__field(unsigned long, flags) -			__field(unsigned int, fmode) +			__field(unsigned long, fmode)  			__field(dev_t, dev)  			__field(u64, dir)  			__string(name, ctx->dentry->d_name.name) @@ -492,17 +427,17 @@ TRACE_EVENT(nfs_atomic_open_exit,  			__entry->dev = dir->i_sb->s_dev;  			__entry->dir = NFS_FILEID(dir);  			__entry->flags = flags; -			__entry->fmode = (__force unsigned int)ctx->mode; +			__entry->fmode = (__force unsigned long)ctx->mode;  			__assign_str(name, ctx->dentry->d_name.name);  		),  		TP_printk(  			"error=%ld (%s) flags=0x%lx (%s) fmode=%s "  			"name=%02x:%02x:%llu/%s", -			-__entry->error, nfs_show_status(__entry->error), +			-__entry->error, show_nfs_status(__entry->error),  			__entry->flags, -			show_open_flags(__entry->flags), -			show_fmode_flags(__entry->fmode), +			show_fs_fcntl_open_flags(__entry->flags), +			show_fs_fmode_flags(__entry->fmode),  			MAJOR(__entry->dev), MINOR(__entry->dev),  			(unsigned long long)__entry->dir,  			__get_str(name) @@ -535,7 +470,7 @@ TRACE_EVENT(nfs_create_enter,  		TP_printk(  			"flags=0x%lx (%s) name=%02x:%02x:%llu/%s",  			__entry->flags, -			show_open_flags(__entry->flags), +			show_fs_fcntl_open_flags(__entry->flags),  			MAJOR(__entry->dev), MINOR(__entry->dev),  			(unsigned long long)__entry->dir,  			__get_str(name) @@ -570,9 +505,9 @@ TRACE_EVENT(nfs_create_exit,  		TP_printk(  			"error=%ld (%s) flags=0x%lx (%s) name=%02x:%02x:%llu/%s", -			-__entry->error, nfs_show_status(__entry->error), +			-__entry->error, show_nfs_status(__entry->error),  			__entry->flags, -			show_open_flags(__entry->flags), +			show_fs_fcntl_open_flags(__entry->flags),  			MAJOR(__entry->dev), MINOR(__entry->dev),  			(unsigned long long)__entry->dir,  			__get_str(name) @@ -640,7 +575,7 @@ DECLARE_EVENT_CLASS(nfs_directory_event_done,  		TP_printk(  			"error=%ld (%s) name=%02x:%02x:%llu/%s", -			-__entry->error, nfs_show_status(__entry->error), +			-__entry->error, show_nfs_status(__entry->error),  			MAJOR(__entry->dev), MINOR(__entry->dev),  			(unsigned long long)__entry->dir,  			__get_str(name) @@ -730,7 +665,7 @@ TRACE_EVENT(nfs_link_exit,  		TP_printk(  			"error=%ld (%s) fileid=%02x:%02x:%llu name=%02x:%02x:%llu/%s", -			-__entry->error, nfs_show_status(__entry->error), +			-__entry->error, show_nfs_status(__entry->error),  			MAJOR(__entry->dev), MINOR(__entry->dev),  			__entry->fileid,  			MAJOR(__entry->dev), MINOR(__entry->dev), @@ -817,7 +752,7 @@ DECLARE_EVENT_CLASS(nfs_rename_event_done,  		TP_printk(  			"error=%ld (%s) old_name=%02x:%02x:%llu/%s "  			"new_name=%02x:%02x:%llu/%s", -			-__entry->error, nfs_show_status(__entry->error), +			-__entry->error, show_nfs_status(__entry->error),  			MAJOR(__entry->dev), MINOR(__entry->dev),  			(unsigned long long)__entry->old_dir,  			__get_str(old_name), @@ -871,13 +806,163 @@ TRACE_EVENT(nfs_sillyrename_unlink,  		TP_printk(  			"error=%ld (%s) name=%02x:%02x:%llu/%s", -			-__entry->error, nfs_show_status(__entry->error), +			-__entry->error, show_nfs_status(__entry->error),  			MAJOR(__entry->dev), MINOR(__entry->dev),  			(unsigned long long)__entry->dir,  			__get_str(name)  		)  ); +TRACE_EVENT(nfs_aop_readpage, +		TP_PROTO( +			const struct inode *inode, +			struct page *page +		), + +		TP_ARGS(inode, page), + +		TP_STRUCT__entry( +			__field(dev_t, dev) +			__field(u32, fhandle) +			__field(u64, fileid) +			__field(u64, version) +			__field(loff_t, offset) +		), + +		TP_fast_assign( +			const struct nfs_inode *nfsi = NFS_I(inode); + +			__entry->dev = inode->i_sb->s_dev; +			__entry->fileid = nfsi->fileid; +			__entry->fhandle = nfs_fhandle_hash(&nfsi->fh); +			__entry->version = inode_peek_iversion_raw(inode); +			__entry->offset = page_index(page) << PAGE_SHIFT; +		), + +		TP_printk( +			"fileid=%02x:%02x:%llu fhandle=0x%08x version=%llu offset=%lld", +			MAJOR(__entry->dev), MINOR(__entry->dev), +			(unsigned long long)__entry->fileid, +			__entry->fhandle, __entry->version, +			__entry->offset +		) +); + +TRACE_EVENT(nfs_aop_readpage_done, +		TP_PROTO( +			const struct inode *inode, +			struct page *page, +			int ret +		), + +		TP_ARGS(inode, page, ret), + +		TP_STRUCT__entry( +			__field(dev_t, dev) +			__field(u32, fhandle) +			__field(int, ret) +			__field(u64, fileid) +			__field(u64, version) +			__field(loff_t, offset) +		), + +		TP_fast_assign( +			const struct nfs_inode *nfsi = NFS_I(inode); + +			__entry->dev = inode->i_sb->s_dev; +			__entry->fileid = nfsi->fileid; +			__entry->fhandle = nfs_fhandle_hash(&nfsi->fh); +			__entry->version = inode_peek_iversion_raw(inode); +			__entry->offset = page_index(page) << PAGE_SHIFT; +			__entry->ret = ret; +		), + +		TP_printk( +			"fileid=%02x:%02x:%llu fhandle=0x%08x version=%llu offset=%lld ret=%d", +			MAJOR(__entry->dev), MINOR(__entry->dev), +			(unsigned long long)__entry->fileid, +			__entry->fhandle, __entry->version, +			__entry->offset, __entry->ret +		) +); + +TRACE_EVENT(nfs_aop_readahead, +		TP_PROTO( +			const struct inode *inode, +			struct page *page, +			unsigned int nr_pages +		), + +		TP_ARGS(inode, page, nr_pages), + +		TP_STRUCT__entry( +			__field(dev_t, dev) +			__field(u32, fhandle) +			__field(u64, fileid) +			__field(u64, version) +			__field(loff_t, offset) +			__field(unsigned int, nr_pages) +		), + +		TP_fast_assign( +			const struct nfs_inode *nfsi = NFS_I(inode); + +			__entry->dev = inode->i_sb->s_dev; +			__entry->fileid = nfsi->fileid; +			__entry->fhandle = nfs_fhandle_hash(&nfsi->fh); +			__entry->version = inode_peek_iversion_raw(inode); +			__entry->offset = page_index(page) << PAGE_SHIFT; +			__entry->nr_pages = nr_pages; +		), + +		TP_printk( +			"fileid=%02x:%02x:%llu fhandle=0x%08x version=%llu offset=%lld nr_pages=%u", +			MAJOR(__entry->dev), MINOR(__entry->dev), +			(unsigned long long)__entry->fileid, +			__entry->fhandle, __entry->version, +			__entry->offset, __entry->nr_pages +		) +); + +TRACE_EVENT(nfs_aop_readahead_done, +		TP_PROTO( +			const struct inode *inode, +			unsigned int nr_pages, +			int ret +		), + +		TP_ARGS(inode, nr_pages, ret), + +		TP_STRUCT__entry( +			__field(dev_t, dev) +			__field(u32, fhandle) +			__field(int, ret) +			__field(u64, fileid) +			__field(u64, version) +			__field(loff_t, offset) +			__field(unsigned int, nr_pages) +		), + +		TP_fast_assign( +			const struct nfs_inode *nfsi = NFS_I(inode); + +			__entry->dev = inode->i_sb->s_dev; +			__entry->fileid = nfsi->fileid; +			__entry->fhandle = nfs_fhandle_hash(&nfsi->fh); +			__entry->version = inode_peek_iversion_raw(inode); +			__entry->nr_pages = nr_pages; +			__entry->ret = ret; +		), + +		TP_printk( +			"fileid=%02x:%02x:%llu fhandle=0x%08x version=%llu nr_pages=%u ret=%d", +			MAJOR(__entry->dev), MINOR(__entry->dev), +			(unsigned long long)__entry->fileid, +			__entry->fhandle, __entry->version, +			__entry->nr_pages, __entry->ret +		) +); +  TRACE_EVENT(nfs_initiate_read,  		TP_PROTO(  			const struct nfs_pgio_header *hdr @@ -1054,16 +1139,6 @@ TRACE_EVENT(nfs_pgio_error,  	)  ); -TRACE_DEFINE_ENUM(NFS_UNSTABLE); -TRACE_DEFINE_ENUM(NFS_DATA_SYNC); -TRACE_DEFINE_ENUM(NFS_FILE_SYNC); - -#define nfs_show_stable(stable) \ -	__print_symbolic(stable, \ -			{ NFS_UNSTABLE, "UNSTABLE" }, \ -			{ NFS_DATA_SYNC, "DATA_SYNC" }, \ -			{ NFS_FILE_SYNC, "FILE_SYNC" }) -  TRACE_EVENT(nfs_initiate_write,  		TP_PROTO(  			const struct nfs_pgio_header *hdr @@ -1077,7 +1152,7 @@ TRACE_EVENT(nfs_initiate_write,  			__field(u64, fileid)  			__field(loff_t, offset)  			__field(u32, count) -			__field(enum nfs3_stable_how, stable) +			__field(unsigned long, stable)  		),  		TP_fast_assign( @@ -1101,7 +1176,7 @@ TRACE_EVENT(nfs_initiate_write,  			(unsigned long long)__entry->fileid,  			__entry->fhandle,  			(long long)__entry->offset, __entry->count, -			nfs_show_stable(__entry->stable) +			show_nfs_stable_how(__entry->stable)  		)  ); @@ -1121,7 +1196,7 @@ TRACE_EVENT(nfs_writeback_done,  			__field(u32, arg_count)  			__field(u32, res_count)  			__field(int, status) -			__field(enum nfs3_stable_how, stable) +			__field(unsigned long, stable)  			__array(char, verifier, NFS4_VERIFIER_SIZE)  		), @@ -1154,8 +1229,8 @@ TRACE_EVENT(nfs_writeback_done,  			__entry->fhandle,  			(long long)__entry->offset, __entry->arg_count,  			__entry->res_count, __entry->status, -			nfs_show_stable(__entry->stable), -			__print_hex_str(__entry->verifier, NFS4_VERIFIER_SIZE) +			show_nfs_stable_how(__entry->stable), +			show_nfs4_verifier(__entry->verifier)  		)  ); @@ -1256,7 +1331,7 @@ TRACE_EVENT(nfs_commit_done,  			__field(u64, fileid)  			__field(loff_t, offset)  			__field(int, status) -			__field(enum nfs3_stable_how, stable) +			__field(unsigned long, stable)  			__array(char, verifier, NFS4_VERIFIER_SIZE)  		), @@ -1285,8 +1360,8 @@ TRACE_EVENT(nfs_commit_done,  			(unsigned long long)__entry->fileid,  			__entry->fhandle,  			(long long)__entry->offset, __entry->status, -			nfs_show_stable(__entry->stable), -			__print_hex_str(__entry->verifier, NFS4_VERIFIER_SIZE) +			show_nfs_stable_how(__entry->stable), +			show_nfs4_verifier(__entry->verifier)  		)  ); @@ -1323,76 +1398,6 @@ TRACE_EVENT(nfs_fh_to_dentry,  		)  ); -TRACE_DEFINE_ENUM(NFS_OK); -TRACE_DEFINE_ENUM(NFSERR_PERM); -TRACE_DEFINE_ENUM(NFSERR_NOENT); -TRACE_DEFINE_ENUM(NFSERR_IO); -TRACE_DEFINE_ENUM(NFSERR_NXIO); -TRACE_DEFINE_ENUM(ECHILD); -TRACE_DEFINE_ENUM(NFSERR_EAGAIN); -TRACE_DEFINE_ENUM(NFSERR_ACCES); -TRACE_DEFINE_ENUM(NFSERR_EXIST); -TRACE_DEFINE_ENUM(NFSERR_XDEV); -TRACE_DEFINE_ENUM(NFSERR_NODEV); -TRACE_DEFINE_ENUM(NFSERR_NOTDIR); -TRACE_DEFINE_ENUM(NFSERR_ISDIR); -TRACE_DEFINE_ENUM(NFSERR_INVAL); -TRACE_DEFINE_ENUM(NFSERR_FBIG); -TRACE_DEFINE_ENUM(NFSERR_NOSPC); -TRACE_DEFINE_ENUM(NFSERR_ROFS); -TRACE_DEFINE_ENUM(NFSERR_MLINK); -TRACE_DEFINE_ENUM(NFSERR_OPNOTSUPP); -TRACE_DEFINE_ENUM(NFSERR_NAMETOOLONG); -TRACE_DEFINE_ENUM(NFSERR_NOTEMPTY); -TRACE_DEFINE_ENUM(NFSERR_DQUOT); -TRACE_DEFINE_ENUM(NFSERR_STALE); -TRACE_DEFINE_ENUM(NFSERR_REMOTE); -TRACE_DEFINE_ENUM(NFSERR_WFLUSH); -TRACE_DEFINE_ENUM(NFSERR_BADHANDLE); -TRACE_DEFINE_ENUM(NFSERR_NOT_SYNC); -TRACE_DEFINE_ENUM(NFSERR_BAD_COOKIE); -TRACE_DEFINE_ENUM(NFSERR_NOTSUPP); -TRACE_DEFINE_ENUM(NFSERR_TOOSMALL); -TRACE_DEFINE_ENUM(NFSERR_SERVERFAULT); -TRACE_DEFINE_ENUM(NFSERR_BADTYPE); -TRACE_DEFINE_ENUM(NFSERR_JUKEBOX); - -#define nfs_show_status(x) \ -	__print_symbolic(x, \ -			{ NFS_OK, "OK" }, \ -			{ NFSERR_PERM, "PERM" }, \ -			{ NFSERR_NOENT, "NOENT" }, \ -			{ NFSERR_IO, "IO" }, \ -			{ NFSERR_NXIO, "NXIO" }, \ -			{ ECHILD, "CHILD" }, \ -			{ NFSERR_EAGAIN, "AGAIN" }, \ -			{ NFSERR_ACCES, "ACCES" }, \ -			{ NFSERR_EXIST, "EXIST" }, \ -			{ NFSERR_XDEV, "XDEV" }, \ -			{ NFSERR_NODEV, "NODEV" }, \ -			{ NFSERR_NOTDIR, "NOTDIR" }, \ -			{ NFSERR_ISDIR, "ISDIR" }, \ -			{ NFSERR_INVAL, "INVAL" }, \ -			{ NFSERR_FBIG, "FBIG" }, \ -			{ NFSERR_NOSPC, "NOSPC" }, \ -			{ NFSERR_ROFS, "ROFS" }, \ -			{ NFSERR_MLINK, "MLINK" }, \ -			{ NFSERR_OPNOTSUPP, "OPNOTSUPP" }, \ -			{ NFSERR_NAMETOOLONG, "NAMETOOLONG" }, \ -			{ NFSERR_NOTEMPTY, "NOTEMPTY" }, \ -			{ NFSERR_DQUOT, "DQUOT" }, \ -			{ NFSERR_STALE, "STALE" }, \ -			{ NFSERR_REMOTE, "REMOTE" }, \ -			{ NFSERR_WFLUSH, "WFLUSH" }, \ -			{ NFSERR_BADHANDLE, "BADHANDLE" }, \ -			{ NFSERR_NOT_SYNC, "NOTSYNC" }, \ -			{ NFSERR_BAD_COOKIE, "BADCOOKIE" }, \ -			{ NFSERR_NOTSUPP, "NOTSUPP" }, \ -			{ NFSERR_TOOSMALL, "TOOSMALL" }, \ -			{ NFSERR_SERVERFAULT, "REMOTEIO" }, \ -			{ NFSERR_BADTYPE, "BADTYPE" }, \ -			{ NFSERR_JUKEBOX, "JUKEBOX" }) -  DECLARE_EVENT_CLASS(nfs_xdr_event,  		TP_PROTO(  			const struct xdr_stream *xdr, @@ -1427,12 +1432,12 @@ DECLARE_EVENT_CLASS(nfs_xdr_event,  			__assign_str(procedure, task->tk_msg.rpc_proc->p_name);  		), -		TP_printk( -			"task:%u@%d xid=0x%08x %sv%d %s error=%ld (%s)", +		TP_printk(SUNRPC_TRACE_TASK_SPECIFIER +			  " xid=0x%08x %sv%d %s error=%ld (%s)",  			__entry->task_id, __entry->client_id, __entry->xid,  			__get_str(program), __entry->version,  			__get_str(procedure), -__entry->error, -			nfs_show_status(__entry->error) +			show_nfs_status(__entry->error)  		)  );  #define DEFINE_NFS_XDR_EVENT(name) \ diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c index cc232d1f16f2..ad7f83dc9a2d 100644 --- a/fs/nfs/pagelist.c +++ b/fs/nfs/pagelist.c @@ -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) diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h index d810ae674f4e..f4d7548d67b2 100644 --- a/fs/nfs/pnfs.h +++ b/fs/nfs/pnfs.h @@ -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; diff --git a/fs/nfs/pnfs_nfs.c b/fs/nfs/pnfs_nfs.c index cf19914fec81..316f68f96e57 100644 --- a/fs/nfs/pnfs_nfs.c +++ b/fs/nfs/pnfs_nfs.c @@ -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; diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c index ea19dbf12301..73dcaa99fa9b 100644 --- a/fs/nfs/proc.c +++ b/fs/nfs/proc.c @@ -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); diff --git a/fs/nfs/read.c b/fs/nfs/read.c index 08d6cc57cbc3..d11af2a9299c 100644 --- a/fs/nfs/read.c +++ b/fs/nfs/read.c @@ -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 @@ out_wait:  	}  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;  } diff --git a/fs/nfs/super.c b/fs/nfs/super.c index e65c83494c05..3aced401735c 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -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); diff --git a/fs/nfs/write.c b/fs/nfs/write.c index eae9bf114041..9b7619ce17a7 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -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 (;;) { diff --git a/fs/nfsd/trace.h b/fs/nfsd/trace.h index 538520957a81..f1e0d3c51bc2 100644 --- a/fs/nfsd/trace.h +++ b/fs/nfsd/trace.h @@ -9,6 +9,7 @@  #define _NFSD_TRACE_H  #include <linux/tracepoint.h> +  #include "export.h"  #include "nfsfh.h" diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h index 15004c469807..5662d8be04eb 100644 --- a/include/linux/nfs4.h +++ b/include/linux/nfs4.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 */ diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index b9a8b925db43..05f249f20f55 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -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;  }  /* diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index e9698b6278a5..967a0098f0a9 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -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); diff --git a/include/linux/pnfs_osd_xdr.h b/include/linux/pnfs_osd_xdr.h deleted file mode 100644 index 17d7d0d20eca..000000000000 --- a/include/linux/pnfs_osd_xdr.h +++ /dev/null @@ -1,317 +0,0 @@ -/* - *  pNFS-osd on-the-wire data structures - * - *  Copyright (C) 2007 Panasas Inc. [year of first publication] - *  All rights reserved. - * - *  Benny Halevy <[email protected]> - *  Boaz Harrosh <[email protected]> - * - *  This program is free software; you can redistribute it and/or modify - *  it under the terms of the GNU General Public License version 2 - *  See the file COPYING included with this distribution for more details. - * - *  Redistribution and use in source and binary forms, with or without - *  modification, are permitted provided that the following conditions - *  are met: - * - *  1. Redistributions of source code must retain the above copyright - *     notice, this list of conditions and the following disclaimer. - *  2. Redistributions in binary form must reproduce the above copyright - *     notice, this list of conditions and the following disclaimer in the - *     documentation and/or other materials provided with the distribution. - *  3. Neither the name of the Panasas company nor the names of its - *     contributors may be used to endorse or promote products derived - *     from this software without specific prior written permission. - * - *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - *  DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - *  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef __PNFS_OSD_XDR_H__ -#define __PNFS_OSD_XDR_H__ - -#include <linux/nfs_fs.h> - -/* - * draft-ietf-nfsv4-minorversion-22 - * draft-ietf-nfsv4-pnfs-obj-12 - */ - -/* Layout Structure */ - -enum pnfs_osd_raid_algorithm4 { -	PNFS_OSD_RAID_0		= 1, -	PNFS_OSD_RAID_4		= 2, -	PNFS_OSD_RAID_5		= 3, -	PNFS_OSD_RAID_PQ	= 4     /* Reed-Solomon P+Q */ -}; - -/*   struct pnfs_osd_data_map4 { - *       uint32_t                    odm_num_comps; - *       length4                     odm_stripe_unit; - *       uint32_t                    odm_group_width; - *       uint32_t                    odm_group_depth; - *       uint32_t                    odm_mirror_cnt; - *       pnfs_osd_raid_algorithm4    odm_raid_algorithm; - *   }; - */ -struct pnfs_osd_data_map { -	u32	odm_num_comps; -	u64	odm_stripe_unit; -	u32	odm_group_width; -	u32	odm_group_depth; -	u32	odm_mirror_cnt; -	u32	odm_raid_algorithm; -}; - -/*   struct pnfs_osd_objid4 { - *       deviceid4       oid_device_id; - *       uint64_t        oid_partition_id; - *       uint64_t        oid_object_id; - *   }; - */ -struct pnfs_osd_objid { -	struct nfs4_deviceid	oid_device_id; -	u64			oid_partition_id; -	u64			oid_object_id; -}; - -/* For printout. I use: - * kprint("dev(%llx:%llx)", _DEVID_LO(pointer), _DEVID_HI(pointer)); - * BE style - */ -#define _DEVID_LO(oid_device_id) \ -	(unsigned long long)be64_to_cpup((__be64 *)(oid_device_id)->data) - -#define _DEVID_HI(oid_device_id) \ -	(unsigned long long)be64_to_cpup(((__be64 *)(oid_device_id)->data) + 1) - -enum pnfs_osd_version { -	PNFS_OSD_MISSING              = 0, -	PNFS_OSD_VERSION_1            = 1, -	PNFS_OSD_VERSION_2            = 2 -}; - -struct pnfs_osd_opaque_cred { -	u32 cred_len; -	void *cred; -}; - -enum pnfs_osd_cap_key_sec { -	PNFS_OSD_CAP_KEY_SEC_NONE     = 0, -	PNFS_OSD_CAP_KEY_SEC_SSV      = 1, -}; - -/*   struct pnfs_osd_object_cred4 { - *       pnfs_osd_objid4         oc_object_id; - *       pnfs_osd_version4       oc_osd_version; - *       pnfs_osd_cap_key_sec4   oc_cap_key_sec; - *       opaque                  oc_capability_key<>; - *       opaque                  oc_capability<>; - *   }; - */ -struct pnfs_osd_object_cred { -	struct pnfs_osd_objid		oc_object_id; -	u32				oc_osd_version; -	u32				oc_cap_key_sec; -	struct pnfs_osd_opaque_cred	oc_cap_key; -	struct pnfs_osd_opaque_cred	oc_cap; -}; - -/*   struct pnfs_osd_layout4 { - *       pnfs_osd_data_map4      olo_map; - *       uint32_t                olo_comps_index; - *       pnfs_osd_object_cred4   olo_components<>; - *   }; - */ -struct pnfs_osd_layout { -	struct pnfs_osd_data_map	olo_map; -	u32				olo_comps_index; -	u32				olo_num_comps; -	struct pnfs_osd_object_cred	*olo_comps; -}; - -/* Device Address */ -enum pnfs_osd_targetid_type { -	OBJ_TARGET_ANON = 1, -	OBJ_TARGET_SCSI_NAME = 2, -	OBJ_TARGET_SCSI_DEVICE_ID = 3, -}; - -/*   union pnfs_osd_targetid4 switch (pnfs_osd_targetid_type4 oti_type) { - *       case OBJ_TARGET_SCSI_NAME: - *           string              oti_scsi_name<>; - * - *       case OBJ_TARGET_SCSI_DEVICE_ID: - *           opaque              oti_scsi_device_id<>; - * - *       default: - *           void; - *   }; - * - *   union pnfs_osd_targetaddr4 switch (bool ota_available) { - *       case TRUE: - *           netaddr4            ota_netaddr; - *       case FALSE: - *           void; - *   }; - * - *   struct pnfs_osd_deviceaddr4 { - *       pnfs_osd_targetid4      oda_targetid; - *       pnfs_osd_targetaddr4    oda_targetaddr; - *       uint64_t                oda_lun; - *       opaque                  oda_systemid<>; - *       pnfs_osd_object_cred4   oda_root_obj_cred; - *       opaque                  oda_osdname<>; - *   }; - */ -struct pnfs_osd_targetid { -	u32				oti_type; -	struct nfs4_string		oti_scsi_device_id; -}; - -/*   struct netaddr4 { - *       // see struct rpcb in RFC1833 - *       string r_netid<>;    // network id - *       string r_addr<>;     // universal address - *   }; - */ -struct pnfs_osd_net_addr { -	struct nfs4_string	r_netid; -	struct nfs4_string	r_addr; -}; - -struct pnfs_osd_targetaddr { -	u32				ota_available; -	struct pnfs_osd_net_addr	ota_netaddr; -}; - -struct pnfs_osd_deviceaddr { -	struct pnfs_osd_targetid	oda_targetid; -	struct pnfs_osd_targetaddr	oda_targetaddr; -	u8				oda_lun[8]; -	struct nfs4_string		oda_systemid; -	struct pnfs_osd_object_cred	oda_root_obj_cred; -	struct nfs4_string		oda_osdname; -}; - -/* LAYOUTCOMMIT: layoutupdate */ - -/*   union pnfs_osd_deltaspaceused4 switch (bool dsu_valid) { - *       case TRUE: - *           int64_t     dsu_delta; - *       case FALSE: - *           void; - *   }; - * - *   struct pnfs_osd_layoutupdate4 { - *       pnfs_osd_deltaspaceused4    olu_delta_space_used; - *       bool                        olu_ioerr_flag; - *   }; - */ -struct pnfs_osd_layoutupdate { -	u32	dsu_valid; -	s64	dsu_delta; -	u32	olu_ioerr_flag; -}; - -/* LAYOUTRETURN: I/O Rrror Report */ - -enum pnfs_osd_errno { -	PNFS_OSD_ERR_EIO		= 1, -	PNFS_OSD_ERR_NOT_FOUND		= 2, -	PNFS_OSD_ERR_NO_SPACE		= 3, -	PNFS_OSD_ERR_BAD_CRED		= 4, -	PNFS_OSD_ERR_NO_ACCESS		= 5, -	PNFS_OSD_ERR_UNREACHABLE	= 6, -	PNFS_OSD_ERR_RESOURCE		= 7 -}; - -/*   struct pnfs_osd_ioerr4 { - *       pnfs_osd_objid4     oer_component; - *       length4             oer_comp_offset; - *       length4             oer_comp_length; - *       bool                oer_iswrite; - *       pnfs_osd_errno4     oer_errno; - *   }; - */ -struct pnfs_osd_ioerr { -	struct pnfs_osd_objid	oer_component; -	u64			oer_comp_offset; -	u64			oer_comp_length; -	u32			oer_iswrite; -	u32			oer_errno; -}; - -/* OSD XDR Client API */ -/* Layout helpers */ -/* Layout decoding is done in two parts: - * 1. First Call pnfs_osd_xdr_decode_layout_map to read in only the header part - *    of the layout. @iter members need not be initialized. - *    Returned: - *             @layout members are set. (@layout->olo_comps set to NULL). - * - *             Zero on success, or negative error if passed xdr is broken. - * - * 2. 2nd Call pnfs_osd_xdr_decode_layout_comp() in a loop until it returns - *    false, to decode the next component. - *    Returned: - *       true if there is more to decode or false if we are done or error. - * - * Example: - *	struct pnfs_osd_xdr_decode_layout_iter iter; - *	struct pnfs_osd_layout layout; - *	struct pnfs_osd_object_cred comp; - *	int status; - * - *	status = pnfs_osd_xdr_decode_layout_map(&layout, &iter, xdr); - *	if (unlikely(status)) - *		goto err; - *	while(pnfs_osd_xdr_decode_layout_comp(&comp, &iter, xdr, &status)) { - *		// All of @comp strings point to inside the xdr_buffer - *		// or scrach buffer. Copy them out to user memory eg. - *		copy_single_comp(dest_comp++, &comp); - *	} - *	if (unlikely(status)) - *		goto err; - */ - -struct pnfs_osd_xdr_decode_layout_iter { -	unsigned total_comps; -	unsigned decoded_comps; -}; - -extern int pnfs_osd_xdr_decode_layout_map(struct pnfs_osd_layout *layout, -	struct pnfs_osd_xdr_decode_layout_iter *iter, struct xdr_stream *xdr); - -extern bool pnfs_osd_xdr_decode_layout_comp(struct pnfs_osd_object_cred *comp, -	struct pnfs_osd_xdr_decode_layout_iter *iter, struct xdr_stream *xdr, -	int *err); - -/* Device Info helpers */ - -/* Note: All strings inside @deviceaddr point to space inside @p. - * @p should stay valid while @deviceaddr is in use. - */ -extern void pnfs_osd_xdr_decode_deviceaddr( -	struct pnfs_osd_deviceaddr *deviceaddr, __be32 *p); - -/* layoutupdate (layout_commit) xdr helpers */ -extern int -pnfs_osd_xdr_encode_layoutupdate(struct xdr_stream *xdr, -				 struct pnfs_osd_layoutupdate *lou); - -/* osd_ioerror encoding (layout_return) */ -extern __be32 *pnfs_osd_xdr_ioerr_reserve_space(struct xdr_stream *xdr); -extern void pnfs_osd_xdr_encode_ioerr(__be32 *p, struct pnfs_osd_ioerr *ioerr); - -#endif /* __PNFS_OSD_XDR_H__ */ diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h index a4661646adc9..267b7aeaf1a6 100644 --- a/include/linux/sunrpc/clnt.h +++ b/include/linux/sunrpc/clnt.h @@ -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 */ diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h index a237b8dbf608..db964bb63912 100644 --- a/include/linux/sunrpc/sched.h +++ b/include/linux/sunrpc/sched.h @@ -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) diff --git a/include/trace/events/fs.h b/include/trace/events/fs.h new file mode 100644 index 000000000000..738b97f22f36 --- /dev/null +++ b/include/trace/events/fs.h @@ -0,0 +1,122 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Display helpers for generic filesystem items + * + * Author: Chuck Lever <[email protected]> + * + * Copyright (c) 2020, Oracle and/or its affiliates. + */ + +#include <linux/fs.h> + +#define show_fs_dirent_type(x) \ +	__print_symbolic(x, \ +		{ DT_UNKNOWN,		"UNKNOWN" }, \ +		{ DT_FIFO,		"FIFO" }, \ +		{ DT_CHR,		"CHR" }, \ +		{ DT_DIR,		"DIR" }, \ +		{ DT_BLK,		"BLK" }, \ +		{ DT_REG,		"REG" }, \ +		{ DT_LNK,		"LNK" }, \ +		{ DT_SOCK,		"SOCK" }, \ +		{ DT_WHT,		"WHT" }) + +#define show_fs_fcntl_open_flags(x) \ +	__print_flags(x, "|", \ +		{ O_WRONLY,		"O_WRONLY" }, \ +		{ O_RDWR,		"O_RDWR" }, \ +		{ O_CREAT,		"O_CREAT" }, \ +		{ O_EXCL,		"O_EXCL" }, \ +		{ O_NOCTTY,		"O_NOCTTY" }, \ +		{ O_TRUNC,		"O_TRUNC" }, \ +		{ O_APPEND,		"O_APPEND" }, \ +		{ O_NONBLOCK,		"O_NONBLOCK" }, \ +		{ O_DSYNC,		"O_DSYNC" }, \ +		{ O_DIRECT,		"O_DIRECT" }, \ +		{ O_LARGEFILE,		"O_LARGEFILE" }, \ +		{ O_DIRECTORY,		"O_DIRECTORY" }, \ +		{ O_NOFOLLOW,		"O_NOFOLLOW" }, \ +		{ O_NOATIME,		"O_NOATIME" }, \ +		{ O_CLOEXEC,		"O_CLOEXEC" }) + +#define __fmode_flag(x)	{ (__force unsigned long)FMODE_##x, #x } +#define show_fs_fmode_flags(x) \ +	__print_flags(x, "|", \ +		__fmode_flag(READ), \ +		__fmode_flag(WRITE), \ +		__fmode_flag(EXEC)) + +#ifdef CONFIG_64BIT +#define show_fs_fcntl_cmd(x) \ +	__print_symbolic(x, \ +		{ F_DUPFD,		"DUPFD" }, \ +		{ F_GETFD,		"GETFD" }, \ +		{ F_SETFD,		"SETFD" }, \ +		{ F_GETFL,		"GETFL" }, \ +		{ F_SETFL,		"SETFL" }, \ +		{ F_GETLK,		"GETLK" }, \ +		{ F_SETLK,		"SETLK" }, \ +		{ F_SETLKW,		"SETLKW" }, \ +		{ F_SETOWN,		"SETOWN" }, \ +		{ F_GETOWN,		"GETOWN" }, \ +		{ F_SETSIG,		"SETSIG" }, \ +		{ F_GETSIG,		"GETSIG" }, \ +		{ F_SETOWN_EX,		"SETOWN_EX" }, \ +		{ F_GETOWN_EX,		"GETOWN_EX" }, \ +		{ F_GETOWNER_UIDS,	"GETOWNER_UIDS" }, \ +		{ F_OFD_GETLK,		"OFD_GETLK" }, \ +		{ F_OFD_SETLK,		"OFD_SETLK" }, \ +		{ F_OFD_SETLKW,		"OFD_SETLKW" }) +#else /* CONFIG_64BIT */ +#define show_fs_fcntl_cmd(x) \ +	__print_symbolic(x, \ +		{ F_DUPFD,		"DUPFD" }, \ +		{ F_GETFD,		"GETFD" }, \ +		{ F_SETFD,		"SETFD" }, \ +		{ F_GETFL,		"GETFL" }, \ +		{ F_SETFL,		"SETFL" }, \ +		{ F_GETLK,		"GETLK" }, \ +		{ F_SETLK,		"SETLK" }, \ +		{ F_SETLKW,		"SETLKW" }, \ +		{ F_SETOWN,		"SETOWN" }, \ +		{ F_GETOWN,		"GETOWN" }, \ +		{ F_SETSIG,		"SETSIG" }, \ +		{ F_GETSIG,		"GETSIG" }, \ +		{ F_GETLK64,		"GETLK64" }, \ +		{ F_SETLK64,		"SETLK64" }, \ +		{ F_SETLKW64,		"SETLKW64" }, \ +		{ F_SETOWN_EX,		"SETOWN_EX" }, \ +		{ F_GETOWN_EX,		"GETOWN_EX" }, \ +		{ F_GETOWNER_UIDS,	"GETOWNER_UIDS" }, \ +		{ F_OFD_GETLK,		"OFD_GETLK" }, \ +		{ F_OFD_SETLK,		"OFD_SETLK" }, \ +		{ F_OFD_SETLKW,		"OFD_SETLKW" }) +#endif /* CONFIG_64BIT */ + +#define show_fs_fcntl_lock_type(x) \ +	__print_symbolic(x, \ +		{ F_RDLCK,		"RDLCK" }, \ +		{ F_WRLCK,		"WRLCK" }, \ +		{ F_UNLCK,		"UNLCK" }) + +#define show_fs_lookup_flags(flags) \ +	__print_flags(flags, "|", \ +		{ LOOKUP_FOLLOW,	"FOLLOW" }, \ +		{ LOOKUP_DIRECTORY,	"DIRECTORY" }, \ +		{ LOOKUP_AUTOMOUNT,	"AUTOMOUNT" }, \ +		{ LOOKUP_EMPTY,		"EMPTY" }, \ +		{ LOOKUP_DOWN,		"DOWN" }, \ +		{ LOOKUP_MOUNTPOINT,	"MOUNTPOINT" }, \ +		{ LOOKUP_REVAL,		"REVAL" }, \ +		{ LOOKUP_RCU,		"RCU" }, \ +		{ LOOKUP_OPEN,		"OPEN" }, \ +		{ LOOKUP_CREATE,	"CREATE" }, \ +		{ LOOKUP_EXCL,		"EXCL" }, \ +		{ LOOKUP_RENAME_TARGET,	"RENAME_TARGET" }, \ +		{ LOOKUP_PARENT,	"PARENT" }, \ +		{ LOOKUP_NO_SYMLINKS,	"NO_SYMLINKS" }, \ +		{ LOOKUP_NO_MAGICLINKS,	"NO_MAGICLINKS" }, \ +		{ LOOKUP_NO_XDEV,	"NO_XDEV" }, \ +		{ LOOKUP_BENEATH,	"BENEATH" }, \ +		{ LOOKUP_IN_ROOT,	"IN_ROOT" }, \ +		{ LOOKUP_CACHED,	"CACHED" }) diff --git a/include/trace/events/nfs.h b/include/trace/events/nfs.h new file mode 100644 index 000000000000..09ffdbb04134 --- /dev/null +++ b/include/trace/events/nfs.h @@ -0,0 +1,375 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Display helpers for NFS protocol elements + * + * Author: Chuck Lever <[email protected]> + * + * Copyright (c) 2020, Oracle and/or its affiliates. + */ + +#include <linux/nfs.h> +#include <linux/nfs4.h> +#include <uapi/linux/nfs.h> + +TRACE_DEFINE_ENUM(NFS_OK); +TRACE_DEFINE_ENUM(NFSERR_PERM); +TRACE_DEFINE_ENUM(NFSERR_NOENT); +TRACE_DEFINE_ENUM(NFSERR_IO); +TRACE_DEFINE_ENUM(NFSERR_NXIO); +TRACE_DEFINE_ENUM(NFSERR_EAGAIN); +TRACE_DEFINE_ENUM(NFSERR_ACCES); +TRACE_DEFINE_ENUM(NFSERR_EXIST); +TRACE_DEFINE_ENUM(NFSERR_XDEV); +TRACE_DEFINE_ENUM(NFSERR_NODEV); +TRACE_DEFINE_ENUM(NFSERR_NOTDIR); +TRACE_DEFINE_ENUM(NFSERR_ISDIR); +TRACE_DEFINE_ENUM(NFSERR_INVAL); +TRACE_DEFINE_ENUM(NFSERR_FBIG); +TRACE_DEFINE_ENUM(NFSERR_NOSPC); +TRACE_DEFINE_ENUM(NFSERR_ROFS); +TRACE_DEFINE_ENUM(NFSERR_MLINK); +TRACE_DEFINE_ENUM(NFSERR_OPNOTSUPP); +TRACE_DEFINE_ENUM(NFSERR_NAMETOOLONG); +TRACE_DEFINE_ENUM(NFSERR_NOTEMPTY); +TRACE_DEFINE_ENUM(NFSERR_DQUOT); +TRACE_DEFINE_ENUM(NFSERR_STALE); +TRACE_DEFINE_ENUM(NFSERR_REMOTE); +TRACE_DEFINE_ENUM(NFSERR_WFLUSH); +TRACE_DEFINE_ENUM(NFSERR_BADHANDLE); +TRACE_DEFINE_ENUM(NFSERR_NOT_SYNC); +TRACE_DEFINE_ENUM(NFSERR_BAD_COOKIE); +TRACE_DEFINE_ENUM(NFSERR_NOTSUPP); +TRACE_DEFINE_ENUM(NFSERR_TOOSMALL); +TRACE_DEFINE_ENUM(NFSERR_SERVERFAULT); +TRACE_DEFINE_ENUM(NFSERR_BADTYPE); +TRACE_DEFINE_ENUM(NFSERR_JUKEBOX); + +#define show_nfs_status(x) \ +	__print_symbolic(x, \ +		{ NFS_OK,			"OK" }, \ +		{ NFSERR_PERM,			"PERM" }, \ +		{ NFSERR_NOENT,			"NOENT" }, \ +		{ NFSERR_IO,			"IO" }, \ +		{ NFSERR_NXIO,			"NXIO" }, \ +		{ ECHILD,			"CHILD" }, \ +		{ NFSERR_EAGAIN,		"AGAIN" }, \ +		{ NFSERR_ACCES,			"ACCES" }, \ +		{ NFSERR_EXIST,			"EXIST" }, \ +		{ NFSERR_XDEV,			"XDEV" }, \ +		{ NFSERR_NODEV,			"NODEV" }, \ +		{ NFSERR_NOTDIR,		"NOTDIR" }, \ +		{ NFSERR_ISDIR,			"ISDIR" }, \ +		{ NFSERR_INVAL,			"INVAL" }, \ +		{ NFSERR_FBIG,			"FBIG" }, \ +		{ NFSERR_NOSPC,			"NOSPC" }, \ +		{ NFSERR_ROFS,			"ROFS" }, \ +		{ NFSERR_MLINK,			"MLINK" }, \ +		{ NFSERR_OPNOTSUPP,		"OPNOTSUPP" }, \ +		{ NFSERR_NAMETOOLONG,		"NAMETOOLONG" }, \ +		{ NFSERR_NOTEMPTY,		"NOTEMPTY" }, \ +		{ NFSERR_DQUOT,			"DQUOT" }, \ +		{ NFSERR_STALE,			"STALE" }, \ +		{ NFSERR_REMOTE,		"REMOTE" }, \ +		{ NFSERR_WFLUSH,		"WFLUSH" }, \ +		{ NFSERR_BADHANDLE,		"BADHANDLE" }, \ +		{ NFSERR_NOT_SYNC,		"NOTSYNC" }, \ +		{ NFSERR_BAD_COOKIE,		"BADCOOKIE" }, \ +		{ NFSERR_NOTSUPP,		"NOTSUPP" }, \ +		{ NFSERR_TOOSMALL,		"TOOSMALL" }, \ +		{ NFSERR_SERVERFAULT,		"REMOTEIO" }, \ +		{ NFSERR_BADTYPE,		"BADTYPE" }, \ +		{ NFSERR_JUKEBOX,		"JUKEBOX" }) + +TRACE_DEFINE_ENUM(NFS_UNSTABLE); +TRACE_DEFINE_ENUM(NFS_DATA_SYNC); +TRACE_DEFINE_ENUM(NFS_FILE_SYNC); + +#define show_nfs_stable_how(x) \ +	__print_symbolic(x, \ +		{ NFS_UNSTABLE,			"UNSTABLE" }, \ +		{ NFS_DATA_SYNC,		"DATA_SYNC" }, \ +		{ NFS_FILE_SYNC,		"FILE_SYNC" }) + +TRACE_DEFINE_ENUM(NFS4_OK); +TRACE_DEFINE_ENUM(NFS4ERR_ACCESS); +TRACE_DEFINE_ENUM(NFS4ERR_ATTRNOTSUPP); +TRACE_DEFINE_ENUM(NFS4ERR_ADMIN_REVOKED); +TRACE_DEFINE_ENUM(NFS4ERR_BACK_CHAN_BUSY); +TRACE_DEFINE_ENUM(NFS4ERR_BADCHAR); +TRACE_DEFINE_ENUM(NFS4ERR_BADHANDLE); +TRACE_DEFINE_ENUM(NFS4ERR_BADIOMODE); +TRACE_DEFINE_ENUM(NFS4ERR_BADLAYOUT); +TRACE_DEFINE_ENUM(NFS4ERR_BADLABEL); +TRACE_DEFINE_ENUM(NFS4ERR_BADNAME); +TRACE_DEFINE_ENUM(NFS4ERR_BADOWNER); +TRACE_DEFINE_ENUM(NFS4ERR_BADSESSION); +TRACE_DEFINE_ENUM(NFS4ERR_BADSLOT); +TRACE_DEFINE_ENUM(NFS4ERR_BADTYPE); +TRACE_DEFINE_ENUM(NFS4ERR_BADXDR); +TRACE_DEFINE_ENUM(NFS4ERR_BAD_COOKIE); +TRACE_DEFINE_ENUM(NFS4ERR_BAD_HIGH_SLOT); +TRACE_DEFINE_ENUM(NFS4ERR_BAD_RANGE); +TRACE_DEFINE_ENUM(NFS4ERR_BAD_SEQID); +TRACE_DEFINE_ENUM(NFS4ERR_BAD_SESSION_DIGEST); +TRACE_DEFINE_ENUM(NFS4ERR_BAD_STATEID); +TRACE_DEFINE_ENUM(NFS4ERR_CB_PATH_DOWN); +TRACE_DEFINE_ENUM(NFS4ERR_CLID_INUSE); +TRACE_DEFINE_ENUM(NFS4ERR_CLIENTID_BUSY); +TRACE_DEFINE_ENUM(NFS4ERR_COMPLETE_ALREADY); +TRACE_DEFINE_ENUM(NFS4ERR_CONN_NOT_BOUND_TO_SESSION); +TRACE_DEFINE_ENUM(NFS4ERR_DEADLOCK); +TRACE_DEFINE_ENUM(NFS4ERR_DEADSESSION); +TRACE_DEFINE_ENUM(NFS4ERR_DELAY); +TRACE_DEFINE_ENUM(NFS4ERR_DELEG_ALREADY_WANTED); +TRACE_DEFINE_ENUM(NFS4ERR_DELEG_REVOKED); +TRACE_DEFINE_ENUM(NFS4ERR_DENIED); +TRACE_DEFINE_ENUM(NFS4ERR_DIRDELEG_UNAVAIL); +TRACE_DEFINE_ENUM(NFS4ERR_DQUOT); +TRACE_DEFINE_ENUM(NFS4ERR_ENCR_ALG_UNSUPP); +TRACE_DEFINE_ENUM(NFS4ERR_EXIST); +TRACE_DEFINE_ENUM(NFS4ERR_EXPIRED); +TRACE_DEFINE_ENUM(NFS4ERR_FBIG); +TRACE_DEFINE_ENUM(NFS4ERR_FHEXPIRED); +TRACE_DEFINE_ENUM(NFS4ERR_FILE_OPEN); +TRACE_DEFINE_ENUM(NFS4ERR_GRACE); +TRACE_DEFINE_ENUM(NFS4ERR_HASH_ALG_UNSUPP); +TRACE_DEFINE_ENUM(NFS4ERR_INVAL); +TRACE_DEFINE_ENUM(NFS4ERR_IO); +TRACE_DEFINE_ENUM(NFS4ERR_ISDIR); +TRACE_DEFINE_ENUM(NFS4ERR_LAYOUTTRYLATER); +TRACE_DEFINE_ENUM(NFS4ERR_LAYOUTUNAVAILABLE); +TRACE_DEFINE_ENUM(NFS4ERR_LEASE_MOVED); +TRACE_DEFINE_ENUM(NFS4ERR_LOCKED); +TRACE_DEFINE_ENUM(NFS4ERR_LOCKS_HELD); +TRACE_DEFINE_ENUM(NFS4ERR_LOCK_RANGE); +TRACE_DEFINE_ENUM(NFS4ERR_MINOR_VERS_MISMATCH); +TRACE_DEFINE_ENUM(NFS4ERR_MLINK); +TRACE_DEFINE_ENUM(NFS4ERR_MOVED); +TRACE_DEFINE_ENUM(NFS4ERR_NAMETOOLONG); +TRACE_DEFINE_ENUM(NFS4ERR_NOENT); +TRACE_DEFINE_ENUM(NFS4ERR_NOFILEHANDLE); +TRACE_DEFINE_ENUM(NFS4ERR_NOMATCHING_LAYOUT); +TRACE_DEFINE_ENUM(NFS4ERR_NOSPC); +TRACE_DEFINE_ENUM(NFS4ERR_NOTDIR); +TRACE_DEFINE_ENUM(NFS4ERR_NOTEMPTY); +TRACE_DEFINE_ENUM(NFS4ERR_NOTSUPP); +TRACE_DEFINE_ENUM(NFS4ERR_NOT_ONLY_OP); +TRACE_DEFINE_ENUM(NFS4ERR_NOT_SAME); +TRACE_DEFINE_ENUM(NFS4ERR_NO_GRACE); +TRACE_DEFINE_ENUM(NFS4ERR_NXIO); +TRACE_DEFINE_ENUM(NFS4ERR_OLD_STATEID); +TRACE_DEFINE_ENUM(NFS4ERR_OPENMODE); +TRACE_DEFINE_ENUM(NFS4ERR_OP_ILLEGAL); +TRACE_DEFINE_ENUM(NFS4ERR_OP_NOT_IN_SESSION); +TRACE_DEFINE_ENUM(NFS4ERR_PERM); +TRACE_DEFINE_ENUM(NFS4ERR_PNFS_IO_HOLE); +TRACE_DEFINE_ENUM(NFS4ERR_PNFS_NO_LAYOUT); +TRACE_DEFINE_ENUM(NFS4ERR_RECALLCONFLICT); +TRACE_DEFINE_ENUM(NFS4ERR_RECLAIM_BAD); +TRACE_DEFINE_ENUM(NFS4ERR_RECLAIM_CONFLICT); +TRACE_DEFINE_ENUM(NFS4ERR_REJECT_DELEG); +TRACE_DEFINE_ENUM(NFS4ERR_REP_TOO_BIG); +TRACE_DEFINE_ENUM(NFS4ERR_REP_TOO_BIG_TO_CACHE); +TRACE_DEFINE_ENUM(NFS4ERR_REQ_TOO_BIG); +TRACE_DEFINE_ENUM(NFS4ERR_RESOURCE); +TRACE_DEFINE_ENUM(NFS4ERR_RESTOREFH); +TRACE_DEFINE_ENUM(NFS4ERR_RETRY_UNCACHED_REP); +TRACE_DEFINE_ENUM(NFS4ERR_RETURNCONFLICT); +TRACE_DEFINE_ENUM(NFS4ERR_ROFS); +TRACE_DEFINE_ENUM(NFS4ERR_SAME); +TRACE_DEFINE_ENUM(NFS4ERR_SHARE_DENIED); +TRACE_DEFINE_ENUM(NFS4ERR_SEQUENCE_POS); +TRACE_DEFINE_ENUM(NFS4ERR_SEQ_FALSE_RETRY); +TRACE_DEFINE_ENUM(NFS4ERR_SEQ_MISORDERED); +TRACE_DEFINE_ENUM(NFS4ERR_SERVERFAULT); +TRACE_DEFINE_ENUM(NFS4ERR_STALE); +TRACE_DEFINE_ENUM(NFS4ERR_STALE_CLIENTID); +TRACE_DEFINE_ENUM(NFS4ERR_STALE_STATEID); +TRACE_DEFINE_ENUM(NFS4ERR_SYMLINK); +TRACE_DEFINE_ENUM(NFS4ERR_TOOSMALL); +TRACE_DEFINE_ENUM(NFS4ERR_TOO_MANY_OPS); +TRACE_DEFINE_ENUM(NFS4ERR_UNKNOWN_LAYOUTTYPE); +TRACE_DEFINE_ENUM(NFS4ERR_UNSAFE_COMPOUND); +TRACE_DEFINE_ENUM(NFS4ERR_WRONGSEC); +TRACE_DEFINE_ENUM(NFS4ERR_WRONG_CRED); +TRACE_DEFINE_ENUM(NFS4ERR_WRONG_TYPE); +TRACE_DEFINE_ENUM(NFS4ERR_XDEV); + +TRACE_DEFINE_ENUM(NFS4ERR_RESET_TO_MDS); +TRACE_DEFINE_ENUM(NFS4ERR_RESET_TO_PNFS); + +#define show_nfs4_status(x) \ +	__print_symbolic(x, \ +		{ NFS4_OK,			"OK" }, \ +		{ EPERM,			"EPERM" }, \ +		{ ENOENT,			"ENOENT" }, \ +		{ EIO,				"EIO" }, \ +		{ ENXIO,			"ENXIO" }, \ +		{ EACCES,			"EACCES" }, \ +		{ EEXIST,			"EEXIST" }, \ +		{ EXDEV,			"EXDEV" }, \ +		{ ENOTDIR,			"ENOTDIR" }, \ +		{ EISDIR,			"EISDIR" }, \ +		{ EFBIG,			"EFBIG" }, \ +		{ ENOSPC,			"ENOSPC" }, \ +		{ EROFS,			"EROFS" }, \ +		{ EMLINK,			"EMLINK" }, \ +		{ ENAMETOOLONG,			"ENAMETOOLONG" }, \ +		{ ENOTEMPTY,			"ENOTEMPTY" }, \ +		{ EDQUOT,			"EDQUOT" }, \ +		{ ESTALE,			"ESTALE" }, \ +		{ EBADHANDLE,			"EBADHANDLE" }, \ +		{ EBADCOOKIE,			"EBADCOOKIE" }, \ +		{ ENOTSUPP,			"ENOTSUPP" }, \ +		{ ETOOSMALL,			"ETOOSMALL" }, \ +		{ EREMOTEIO,			"EREMOTEIO" }, \ +		{ EBADTYPE,			"EBADTYPE" }, \ +		{ EAGAIN,			"EAGAIN" }, \ +		{ ELOOP,			"ELOOP" }, \ +		{ EOPNOTSUPP,			"EOPNOTSUPP" }, \ +		{ EDEADLK,			"EDEADLK" }, \ +		{ ENOMEM,			"ENOMEM" }, \ +		{ EKEYEXPIRED,			"EKEYEXPIRED" }, \ +		{ ETIMEDOUT,			"ETIMEDOUT" }, \ +		{ ERESTARTSYS,			"ERESTARTSYS" }, \ +		{ ECONNREFUSED,			"ECONNREFUSED" }, \ +		{ ECONNRESET,			"ECONNRESET" }, \ +		{ ENETUNREACH,			"ENETUNREACH" }, \ +		{ EHOSTUNREACH,			"EHOSTUNREACH" }, \ +		{ EHOSTDOWN,			"EHOSTDOWN" }, \ +		{ EPIPE,			"EPIPE" }, \ +		{ EPFNOSUPPORT,			"EPFNOSUPPORT" }, \ +		{ EPROTONOSUPPORT,		"EPROTONOSUPPORT" }, \ +		{ NFS4ERR_ACCESS,		"ACCESS" }, \ +		{ NFS4ERR_ATTRNOTSUPP,		"ATTRNOTSUPP" }, \ +		{ NFS4ERR_ADMIN_REVOKED,	"ADMIN_REVOKED" }, \ +		{ NFS4ERR_BACK_CHAN_BUSY,	"BACK_CHAN_BUSY" }, \ +		{ NFS4ERR_BADCHAR,		"BADCHAR" }, \ +		{ NFS4ERR_BADHANDLE,		"BADHANDLE" }, \ +		{ NFS4ERR_BADIOMODE,		"BADIOMODE" }, \ +		{ NFS4ERR_BADLAYOUT,		"BADLAYOUT" }, \ +		{ NFS4ERR_BADLABEL,		"BADLABEL" }, \ +		{ NFS4ERR_BADNAME,		"BADNAME" }, \ +		{ NFS4ERR_BADOWNER,		"BADOWNER" }, \ +		{ NFS4ERR_BADSESSION,		"BADSESSION" }, \ +		{ NFS4ERR_BADSLOT,		"BADSLOT" }, \ +		{ NFS4ERR_BADTYPE,		"BADTYPE" }, \ +		{ NFS4ERR_BADXDR,		"BADXDR" }, \ +		{ NFS4ERR_BAD_COOKIE,		"BAD_COOKIE" }, \ +		{ NFS4ERR_BAD_HIGH_SLOT,	"BAD_HIGH_SLOT" }, \ +		{ NFS4ERR_BAD_RANGE,		"BAD_RANGE" }, \ +		{ NFS4ERR_BAD_SEQID,		"BAD_SEQID" }, \ +		{ NFS4ERR_BAD_SESSION_DIGEST,	"BAD_SESSION_DIGEST" }, \ +		{ NFS4ERR_BAD_STATEID,		"BAD_STATEID" }, \ +		{ NFS4ERR_CB_PATH_DOWN,		"CB_PATH_DOWN" }, \ +		{ NFS4ERR_CLID_INUSE,		"CLID_INUSE" }, \ +		{ NFS4ERR_CLIENTID_BUSY,	"CLIENTID_BUSY" }, \ +		{ NFS4ERR_COMPLETE_ALREADY,	"COMPLETE_ALREADY" }, \ +		{ NFS4ERR_CONN_NOT_BOUND_TO_SESSION, "CONN_NOT_BOUND_TO_SESSION" }, \ +		{ NFS4ERR_DEADLOCK,		"DEADLOCK" }, \ +		{ NFS4ERR_DEADSESSION,		"DEAD_SESSION" }, \ +		{ NFS4ERR_DELAY,		"DELAY" }, \ +		{ NFS4ERR_DELEG_ALREADY_WANTED,	"DELEG_ALREADY_WANTED" }, \ +		{ NFS4ERR_DELEG_REVOKED,	"DELEG_REVOKED" }, \ +		{ NFS4ERR_DENIED,		"DENIED" }, \ +		{ NFS4ERR_DIRDELEG_UNAVAIL,	"DIRDELEG_UNAVAIL" }, \ +		{ NFS4ERR_DQUOT,		"DQUOT" }, \ +		{ NFS4ERR_ENCR_ALG_UNSUPP,	"ENCR_ALG_UNSUPP" }, \ +		{ NFS4ERR_EXIST,		"EXIST" }, \ +		{ NFS4ERR_EXPIRED,		"EXPIRED" }, \ +		{ NFS4ERR_FBIG,			"FBIG" }, \ +		{ NFS4ERR_FHEXPIRED,		"FHEXPIRED" }, \ +		{ NFS4ERR_FILE_OPEN,		"FILE_OPEN" }, \ +		{ NFS4ERR_GRACE,		"GRACE" }, \ +		{ NFS4ERR_HASH_ALG_UNSUPP,	"HASH_ALG_UNSUPP" }, \ +		{ NFS4ERR_INVAL,		"INVAL" }, \ +		{ NFS4ERR_IO,			"IO" }, \ +		{ NFS4ERR_ISDIR,		"ISDIR" }, \ +		{ NFS4ERR_LAYOUTTRYLATER,	"LAYOUTTRYLATER" }, \ +		{ NFS4ERR_LAYOUTUNAVAILABLE,	"LAYOUTUNAVAILABLE" }, \ +		{ NFS4ERR_LEASE_MOVED,		"LEASE_MOVED" }, \ +		{ NFS4ERR_LOCKED,		"LOCKED" }, \ +		{ NFS4ERR_LOCKS_HELD,		"LOCKS_HELD" }, \ +		{ NFS4ERR_LOCK_RANGE,		"LOCK_RANGE" }, \ +		{ NFS4ERR_MINOR_VERS_MISMATCH,	"MINOR_VERS_MISMATCH" }, \ +		{ NFS4ERR_MLINK,		"MLINK" }, \ +		{ NFS4ERR_MOVED,		"MOVED" }, \ +		{ NFS4ERR_NAMETOOLONG,		"NAMETOOLONG" }, \ +		{ NFS4ERR_NOENT,		"NOENT" }, \ +		{ NFS4ERR_NOFILEHANDLE,		"NOFILEHANDLE" }, \ +		{ NFS4ERR_NOMATCHING_LAYOUT,	"NOMATCHING_LAYOUT" }, \ +		{ NFS4ERR_NOSPC,		"NOSPC" }, \ +		{ NFS4ERR_NOTDIR,		"NOTDIR" }, \ +		{ NFS4ERR_NOTEMPTY,		"NOTEMPTY" }, \ +		{ NFS4ERR_NOTSUPP,		"NOTSUPP" }, \ +		{ NFS4ERR_NOT_ONLY_OP,		"NOT_ONLY_OP" }, \ +		{ NFS4ERR_NOT_SAME,		"NOT_SAME" }, \ +		{ NFS4ERR_NO_GRACE,		"NO_GRACE" }, \ +		{ NFS4ERR_NXIO,			"NXIO" }, \ +		{ NFS4ERR_OLD_STATEID,		"OLD_STATEID" }, \ +		{ NFS4ERR_OPENMODE,		"OPENMODE" }, \ +		{ NFS4ERR_OP_ILLEGAL,		"OP_ILLEGAL" }, \ +		{ NFS4ERR_OP_NOT_IN_SESSION,	"OP_NOT_IN_SESSION" }, \ +		{ NFS4ERR_PERM,			"PERM" }, \ +		{ NFS4ERR_PNFS_IO_HOLE,		"PNFS_IO_HOLE" }, \ +		{ NFS4ERR_PNFS_NO_LAYOUT,	"PNFS_NO_LAYOUT" }, \ +		{ NFS4ERR_RECALLCONFLICT,	"RECALLCONFLICT" }, \ +		{ NFS4ERR_RECLAIM_BAD,		"RECLAIM_BAD" }, \ +		{ NFS4ERR_RECLAIM_CONFLICT,	"RECLAIM_CONFLICT" }, \ +		{ NFS4ERR_REJECT_DELEG,		"REJECT_DELEG" }, \ +		{ NFS4ERR_REP_TOO_BIG,		"REP_TOO_BIG" }, \ +		{ NFS4ERR_REP_TOO_BIG_TO_CACHE,	"REP_TOO_BIG_TO_CACHE" }, \ +		{ NFS4ERR_REQ_TOO_BIG,		"REQ_TOO_BIG" }, \ +		{ NFS4ERR_RESOURCE,		"RESOURCE" }, \ +		{ NFS4ERR_RESTOREFH,		"RESTOREFH" }, \ +		{ NFS4ERR_RETRY_UNCACHED_REP,	"RETRY_UNCACHED_REP" }, \ +		{ NFS4ERR_RETURNCONFLICT,	"RETURNCONFLICT" }, \ +		{ NFS4ERR_ROFS,			"ROFS" }, \ +		{ NFS4ERR_SAME,			"SAME" }, \ +		{ NFS4ERR_SHARE_DENIED,		"SHARE_DENIED" }, \ +		{ NFS4ERR_SEQUENCE_POS,		"SEQUENCE_POS" }, \ +		{ NFS4ERR_SEQ_FALSE_RETRY,	"SEQ_FALSE_RETRY" }, \ +		{ NFS4ERR_SEQ_MISORDERED,	"SEQ_MISORDERED" }, \ +		{ NFS4ERR_SERVERFAULT,		"SERVERFAULT" }, \ +		{ NFS4ERR_STALE,		"STALE" }, \ +		{ NFS4ERR_STALE_CLIENTID,	"STALE_CLIENTID" }, \ +		{ NFS4ERR_STALE_STATEID,	"STALE_STATEID" }, \ +		{ NFS4ERR_SYMLINK,		"SYMLINK" }, \ +		{ NFS4ERR_TOOSMALL,		"TOOSMALL" }, \ +		{ NFS4ERR_TOO_MANY_OPS,		"TOO_MANY_OPS" }, \ +		{ NFS4ERR_UNKNOWN_LAYOUTTYPE,	"UNKNOWN_LAYOUTTYPE" }, \ +		{ NFS4ERR_UNSAFE_COMPOUND,	"UNSAFE_COMPOUND" }, \ +		{ NFS4ERR_WRONGSEC,		"WRONGSEC" }, \ +		{ NFS4ERR_WRONG_CRED,		"WRONG_CRED" }, \ +		{ NFS4ERR_WRONG_TYPE,		"WRONG_TYPE" }, \ +		{ NFS4ERR_XDEV,			"XDEV" }, \ +		/* ***** Internal to Linux NFS client ***** */ \ +		{ NFS4ERR_RESET_TO_MDS,		"RESET_TO_MDS" }, \ +		{ NFS4ERR_RESET_TO_PNFS,	"RESET_TO_PNFS" }) + +#define show_nfs4_verifier(x) \ +	__print_hex_str(x, NFS4_VERIFIER_SIZE) + +TRACE_DEFINE_ENUM(IOMODE_READ); +TRACE_DEFINE_ENUM(IOMODE_RW); +TRACE_DEFINE_ENUM(IOMODE_ANY); + +#define show_pnfs_layout_iomode(x) \ +	__print_symbolic(x, \ +		{ IOMODE_READ,			"READ" }, \ +		{ IOMODE_RW,			"RW" }, \ +		{ IOMODE_ANY,			"ANY" }) + +#define show_nfs4_seq4_status(x) \ +	__print_flags(x, "|", \ +		{ SEQ4_STATUS_CB_PATH_DOWN,		"CB_PATH_DOWN" }, \ +		{ SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRING,	"CB_GSS_CONTEXTS_EXPIRING" }, \ +		{ SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRED,	"CB_GSS_CONTEXTS_EXPIRED" }, \ +		{ SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED, "EXPIRED_ALL_STATE_REVOKED" }, \ +		{ SEQ4_STATUS_EXPIRED_SOME_STATE_REVOKED, "EXPIRED_SOME_STATE_REVOKED" }, \ +		{ SEQ4_STATUS_ADMIN_STATE_REVOKED,	"ADMIN_STATE_REVOKED" }, \ +		{ SEQ4_STATUS_RECALLABLE_STATE_REVOKED,	"RECALLABLE_STATE_REVOKED" }, \ +		{ SEQ4_STATUS_LEASE_MOVED,		"LEASE_MOVED" }, \ +		{ SEQ4_STATUS_RESTART_RECLAIM_NEEDED,	"RESTART_RECLAIM_NEEDED" }, \ +		{ SEQ4_STATUS_CB_PATH_DOWN_SESSION,	"CB_PATH_DOWN_SESSION" }, \ +		{ SEQ4_STATUS_BACKCHANNEL_FAULT,	"BACKCHANNEL_FAULT" }) diff --git a/include/trace/events/rpcgss.h b/include/trace/events/rpcgss.h index b2a2672e6632..3ba63319af3c 100644 --- a/include/trace/events/rpcgss.h +++ b/include/trace/events/rpcgss.h @@ -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) diff --git a/include/trace/events/rpcrdma.h b/include/trace/events/rpcrdma.h index de4195499592..7f46ef621c95 100644 --- a/include/trace/events/rpcrdma.h +++ b/include/trace/events/rpcrdma.h @@ -14,7 +14,9 @@  #include <linux/sunrpc/rpc_rdma_cid.h>  #include <linux/tracepoint.h>  #include <rdma/ib_cm.h> +  #include <trace/events/rdma.h> +#include <trace/events/sunrpc_base.h>  /**   ** Event classes @@ -279,7 +281,8 @@ DECLARE_EVENT_CLASS(xprtrdma_rdch_event,  		__entry->nsegs = nsegs;  	), -	TP_printk("task:%u@%u pos=%u %u@0x%016llx:0x%08x (%s)", +	TP_printk(SUNRPC_TRACE_TASK_SPECIFIER +		  " pos=%u %u@0x%016llx:0x%08x (%s)",  		__entry->task_id, __entry->client_id,  		__entry->pos, __entry->length,  		(unsigned long long)__entry->offset, __entry->handle, @@ -326,7 +329,8 @@ DECLARE_EVENT_CLASS(xprtrdma_wrch_event,  		__entry->nsegs = nsegs;  	), -	TP_printk("task:%u@%u %u@0x%016llx:0x%08x (%s)", +	TP_printk(SUNRPC_TRACE_TASK_SPECIFIER +		  " %u@0x%016llx:0x%08x (%s)",  		__entry->task_id, __entry->client_id,  		__entry->length, (unsigned long long)__entry->offset,  		__entry->handle, @@ -375,10 +379,16 @@ DECLARE_EVENT_CLASS(xprtrdma_mr_class,  	TP_fast_assign(  		const struct rpcrdma_req *req = mr->mr_req; -		const struct rpc_task *task = req->rl_slot.rq_task; -		__entry->task_id = task->tk_pid; -		__entry->client_id = task->tk_client->cl_clid; +		if (req) { +			const struct rpc_task *task = req->rl_slot.rq_task; + +			__entry->task_id = task->tk_pid; +			__entry->client_id = task->tk_client->cl_clid; +		} else { +			__entry->task_id = 0; +			__entry->client_id = -1; +		}  		__entry->mr_id  = mr->mr_ibmr->res.id;  		__entry->nents  = mr->mr_nents;  		__entry->handle = mr->mr_handle; @@ -387,7 +397,8 @@ DECLARE_EVENT_CLASS(xprtrdma_mr_class,  		__entry->dir    = mr->mr_dir;  	), -	TP_printk("task:%u@%u mr.id=%u nents=%d %u@0x%016llx:0x%08x (%s)", +	TP_printk(SUNRPC_TRACE_TASK_SPECIFIER +		  " mr.id=%u nents=%d %u@0x%016llx:0x%08x (%s)",  		__entry->task_id, __entry->client_id,  		__entry->mr_id, __entry->nents, __entry->length,  		(unsigned long long)__entry->offset, __entry->handle, @@ -630,15 +641,16 @@ TRACE_EVENT(xprtrdma_nomrs_err,  		__assign_str(port, rpcrdma_portstr(r_xprt));  	), -	TP_printk("peer=[%s]:%s task:%u@%u", -		__get_str(addr), __get_str(port), -		__entry->task_id, __entry->client_id +	TP_printk(SUNRPC_TRACE_TASK_SPECIFIER " peer=[%s]:%s", +		__entry->task_id, __entry->client_id, +		__get_str(addr), __get_str(port)  	)  );  DEFINE_RDCH_EVENT(read);  DEFINE_WRCH_EVENT(write);  DEFINE_WRCH_EVENT(reply); +DEFINE_WRCH_EVENT(wp);  TRACE_DEFINE_ENUM(rpcrdma_noch);  TRACE_DEFINE_ENUM(rpcrdma_noch_pullup); @@ -693,7 +705,8 @@ TRACE_EVENT(xprtrdma_marshal,  		__entry->wtype = wtype;  	), -	TP_printk("task:%u@%u xid=0x%08x: hdr=%u xdr=%u/%u/%u %s/%s", +	TP_printk(SUNRPC_TRACE_TASK_SPECIFIER +		  " xid=0x%08x hdr=%u xdr=%u/%u/%u %s/%s",  		__entry->task_id, __entry->client_id, __entry->xid,  		__entry->hdrlen,  		__entry->headlen, __entry->pagelen, __entry->taillen, @@ -723,7 +736,7 @@ TRACE_EVENT(xprtrdma_marshal_failed,  		__entry->ret = ret;  	), -	TP_printk("task:%u@%u xid=0x%08x: ret=%d", +	TP_printk(SUNRPC_TRACE_TASK_SPECIFIER " xid=0x%08x ret=%d",  		__entry->task_id, __entry->client_id, __entry->xid,  		__entry->ret  	) @@ -750,7 +763,7 @@ TRACE_EVENT(xprtrdma_prepsend_failed,  		__entry->ret = ret;  	), -	TP_printk("task:%u@%u xid=0x%08x: ret=%d", +	TP_printk(SUNRPC_TRACE_TASK_SPECIFIER " xid=0x%08x ret=%d",  		__entry->task_id, __entry->client_id, __entry->xid,  		__entry->ret  	) @@ -785,7 +798,7 @@ TRACE_EVENT(xprtrdma_post_send,  		__entry->signaled = req->rl_wr.send_flags & IB_SEND_SIGNALED;  	), -	TP_printk("task:%u@%u cq.id=%u cid=%d (%d SGE%s) %s", +	TP_printk(SUNRPC_TRACE_TASK_SPECIFIER " cq.id=%u cid=%d (%d SGE%s) %s",  		__entry->task_id, __entry->client_id,  		__entry->cq_id, __entry->completion_id,  		__entry->num_sge, (__entry->num_sge == 1 ? "" : "s"), @@ -820,7 +833,7 @@ TRACE_EVENT(xprtrdma_post_send_err,  		__entry->rc = rc;  	), -	TP_printk("task:%u@%u cq.id=%u rc=%d", +	TP_printk(SUNRPC_TRACE_TASK_SPECIFIER " cq.id=%u rc=%d",  		__entry->task_id, __entry->client_id,  		__entry->cq_id, __entry->rc  	) @@ -932,7 +945,7 @@ TRACE_EVENT(xprtrdma_post_linv_err,  		__entry->status = status;  	), -	TP_printk("task:%u@%u status=%d", +	TP_printk(SUNRPC_TRACE_TASK_SPECIFIER " status=%d",  		__entry->task_id, __entry->client_id, __entry->status  	)  ); @@ -1120,7 +1133,7 @@ TRACE_EVENT(xprtrdma_reply,  		__entry->credits = credits;  	), -	TP_printk("task:%u@%u xid=0x%08x credits=%u", +	TP_printk(SUNRPC_TRACE_TASK_SPECIFIER " xid=0x%08x credits=%u",  		__entry->task_id, __entry->client_id, __entry->xid,  		__entry->credits  	) @@ -1156,7 +1169,7 @@ TRACE_EVENT(xprtrdma_err_vers,  		__entry->max = be32_to_cpup(max);  	), -	TP_printk("task:%u@%u xid=0x%08x versions=[%u, %u]", +	TP_printk(SUNRPC_TRACE_TASK_SPECIFIER " xid=0x%08x versions=[%u, %u]",  		__entry->task_id, __entry->client_id, __entry->xid,  		__entry->min, __entry->max  	) @@ -1181,7 +1194,7 @@ TRACE_EVENT(xprtrdma_err_chunk,  		__entry->xid = be32_to_cpu(rqst->rq_xid);  	), -	TP_printk("task:%u@%u xid=0x%08x", +	TP_printk(SUNRPC_TRACE_TASK_SPECIFIER " xid=0x%08x",  		__entry->task_id, __entry->client_id, __entry->xid  	)  ); @@ -1207,7 +1220,7 @@ TRACE_EVENT(xprtrdma_err_unrecognized,  		__entry->procedure = be32_to_cpup(procedure);  	), -	TP_printk("task:%u@%u xid=0x%08x procedure=%u", +	TP_printk(SUNRPC_TRACE_TASK_SPECIFIER " xid=0x%08x procedure=%u",  		__entry->task_id, __entry->client_id, __entry->xid,  		__entry->procedure  	) @@ -1239,7 +1252,7 @@ TRACE_EVENT(xprtrdma_fixup,  		__entry->taillen = rqst->rq_rcv_buf.tail[0].iov_len;  	), -	TP_printk("task:%u@%u fixup=%lu xdr=%zu/%u/%zu", +	TP_printk(SUNRPC_TRACE_TASK_SPECIFIER " fixup=%lu xdr=%zu/%u/%zu",  		__entry->task_id, __entry->client_id, __entry->fixup,  		__entry->headlen, __entry->pagelen, __entry->taillen  	) @@ -1289,7 +1302,7 @@ TRACE_EVENT(xprtrdma_mrs_zap,  		__entry->client_id = task->tk_client->cl_clid;  	), -	TP_printk("task:%u@%u", +	TP_printk(SUNRPC_TRACE_TASK_SPECIFIER,  		__entry->task_id, __entry->client_id  	)  ); diff --git a/include/trace/events/sunrpc.h b/include/trace/events/sunrpc.h index 2d04eb96d418..dc922e664820 100644 --- a/include/trace/events/sunrpc.h +++ b/include/trace/events/sunrpc.h @@ -14,6 +14,8 @@  #include <linux/net.h>  #include <linux/tracepoint.h> +#include <trace/events/sunrpc_base.h> +  TRACE_DEFINE_ENUM(SOCK_STREAM);  TRACE_DEFINE_ENUM(SOCK_DGRAM);  TRACE_DEFINE_ENUM(SOCK_RAW); @@ -78,7 +80,8 @@ DECLARE_EVENT_CLASS(rpc_xdr_buf_class,  		__entry->msg_len = xdr->len;  	), -	TP_printk("task:%u@%u head=[%p,%zu] page=%u tail=[%p,%zu] len=%u", +	TP_printk(SUNRPC_TRACE_TASK_SPECIFIER +		  " head=[%p,%zu] page=%u tail=[%p,%zu] len=%u",  		__entry->task_id, __entry->client_id,  		__entry->head_base, __entry->head_len, __entry->page_len,  		__entry->tail_base, __entry->tail_len, __entry->msg_len @@ -114,7 +117,7 @@ DECLARE_EVENT_CLASS(rpc_clnt_class,  		__entry->client_id = clnt->cl_clid;  	), -	TP_printk("clid=%u", __entry->client_id) +	TP_printk("client=" SUNRPC_TRACE_CLID_SPECIFIER, __entry->client_id)  );  #define DEFINE_RPC_CLNT_EVENT(name)					\ @@ -158,7 +161,8 @@ TRACE_EVENT(rpc_clnt_new,  		__assign_str(server, server);  	), -	TP_printk("client=%u peer=[%s]:%s program=%s server=%s", +	TP_printk("client=" SUNRPC_TRACE_CLID_SPECIFIER +		  " peer=[%s]:%s program=%s server=%s",  		__entry->client_id, __get_str(addr), __get_str(port),  		__get_str(program), __get_str(server))  ); @@ -206,7 +210,8 @@ TRACE_EVENT(rpc_clnt_clone_err,  		__entry->error = error;  	), -	TP_printk("client=%u error=%d", __entry->client_id, __entry->error) +	TP_printk("client=" SUNRPC_TRACE_CLID_SPECIFIER " error=%d", +		__entry->client_id, __entry->error)  ); @@ -248,7 +253,7 @@ DECLARE_EVENT_CLASS(rpc_task_status,  		__entry->status = task->tk_status;  	), -	TP_printk("task:%u@%u status=%d", +	TP_printk(SUNRPC_TRACE_TASK_SPECIFIER " status=%d",  		__entry->task_id, __entry->client_id,  		__entry->status)  ); @@ -288,7 +293,7 @@ TRACE_EVENT(rpc_request,  		__assign_str(procname, rpc_proc_name(task));  	), -	TP_printk("task:%u@%u %sv%d %s (%ssync)", +	TP_printk(SUNRPC_TRACE_TASK_SPECIFIER " %sv%d %s (%ssync)",  		__entry->task_id, __entry->client_id,  		__get_str(progname), __entry->version,  		__get_str(procname), __entry->async ? "a": "" @@ -348,7 +353,8 @@ DECLARE_EVENT_CLASS(rpc_task_running,  		__entry->flags = task->tk_flags;  		), -	TP_printk("task:%u@%d flags=%s runstate=%s status=%d action=%ps", +	TP_printk(SUNRPC_TRACE_TASK_SPECIFIER +		  " flags=%s runstate=%s status=%d action=%ps",  		__entry->task_id, __entry->client_id,  		rpc_show_task_flags(__entry->flags),  		rpc_show_runstate(__entry->runstate), @@ -372,6 +378,7 @@ DEFINE_RPC_RUNNING_EVENT(complete);  DEFINE_RPC_RUNNING_EVENT(timeout);  DEFINE_RPC_RUNNING_EVENT(signalled);  DEFINE_RPC_RUNNING_EVENT(end); +DEFINE_RPC_RUNNING_EVENT(call_done);  DECLARE_EVENT_CLASS(rpc_task_queued, @@ -400,7 +407,8 @@ DECLARE_EVENT_CLASS(rpc_task_queued,  		__assign_str(q_name, rpc_qname(q));  		), -	TP_printk("task:%u@%d flags=%s runstate=%s status=%d timeout=%lu queue=%s", +	TP_printk(SUNRPC_TRACE_TASK_SPECIFIER +		  " flags=%s runstate=%s status=%d timeout=%lu queue=%s",  		__entry->task_id, __entry->client_id,  		rpc_show_task_flags(__entry->flags),  		rpc_show_runstate(__entry->runstate), @@ -436,7 +444,7 @@ DECLARE_EVENT_CLASS(rpc_failure,  		__entry->client_id = task->tk_client->cl_clid;  	), -	TP_printk("task:%u@%u", +	TP_printk(SUNRPC_TRACE_TASK_SPECIFIER,  		__entry->task_id, __entry->client_id)  ); @@ -478,7 +486,8 @@ DECLARE_EVENT_CLASS(rpc_reply_event,  		__assign_str(servername, task->tk_xprt->servername);  	), -	TP_printk("task:%u@%d server=%s xid=0x%08x %sv%d %s", +	TP_printk(SUNRPC_TRACE_TASK_SPECIFIER +		  " server=%s xid=0x%08x %sv%d %s",  		__entry->task_id, __entry->client_id, __get_str(servername),  		__entry->xid, __get_str(progname), __entry->version,  		__get_str(procname)) @@ -538,7 +547,8 @@ TRACE_EVENT(rpc_buf_alloc,  		__entry->status = status;  	), -	TP_printk("task:%u@%u callsize=%zu recvsize=%zu status=%d", +	TP_printk(SUNRPC_TRACE_TASK_SPECIFIER +		  " callsize=%zu recvsize=%zu status=%d",  		__entry->task_id, __entry->client_id,  		__entry->callsize, __entry->recvsize, __entry->status  	) @@ -567,7 +577,8 @@ TRACE_EVENT(rpc_call_rpcerror,  		__entry->rpc_status = rpc_status;  	), -	TP_printk("task:%u@%u tk_status=%d rpc_status=%d", +	TP_printk(SUNRPC_TRACE_TASK_SPECIFIER +		  " tk_status=%d rpc_status=%d",  		__entry->task_id, __entry->client_id,  		__entry->tk_status, __entry->rpc_status)  ); @@ -607,7 +618,8 @@ TRACE_EVENT(rpc_stats_latency,  		__entry->execute = ktime_to_us(execute);  	), -	TP_printk("task:%u@%d xid=0x%08x %sv%d %s backlog=%lu rtt=%lu execute=%lu", +	TP_printk(SUNRPC_TRACE_TASK_SPECIFIER +		  " xid=0x%08x %sv%d %s backlog=%lu rtt=%lu execute=%lu",  		__entry->task_id, __entry->client_id, __entry->xid,  		__get_str(progname), __entry->version, __get_str(procname),  		__entry->backlog, __entry->rtt, __entry->execute) @@ -651,8 +663,8 @@ TRACE_EVENT(rpc_xdr_overflow,  			__entry->version = task->tk_client->cl_vers;  			__assign_str(procedure, task->tk_msg.rpc_proc->p_name);  		} else { -			__entry->task_id = 0; -			__entry->client_id = 0; +			__entry->task_id = -1; +			__entry->client_id = -1;  			__assign_str(progname, "unknown");  			__entry->version = 0;  			__assign_str(procedure, "unknown"); @@ -668,8 +680,8 @@ TRACE_EVENT(rpc_xdr_overflow,  		__entry->len = xdr->buf->len;  	), -	TP_printk( -		"task:%u@%u %sv%d %s requested=%zu p=%p end=%p xdr=[%p,%zu]/%u/[%p,%zu]/%u\n", +	TP_printk(SUNRPC_TRACE_TASK_SPECIFIER +		  " %sv%d %s requested=%zu p=%p end=%p xdr=[%p,%zu]/%u/[%p,%zu]/%u\n",  		__entry->task_id, __entry->client_id,  		__get_str(progname), __entry->version, __get_str(procedure),  		__entry->requested, __entry->p, __entry->end, @@ -727,8 +739,8 @@ TRACE_EVENT(rpc_xdr_alignment,  		__entry->len = xdr->buf->len;  	), -	TP_printk( -		"task:%u@%u %sv%d %s offset=%zu copied=%u xdr=[%p,%zu]/%u/[%p,%zu]/%u\n", +	TP_printk(SUNRPC_TRACE_TASK_SPECIFIER +		  " %sv%d %s offset=%zu copied=%u xdr=[%p,%zu]/%u/[%p,%zu]/%u\n",  		__entry->task_id, __entry->client_id,  		__get_str(progname), __entry->version, __get_str(procedure),  		__entry->offset, __entry->copied, @@ -917,7 +929,8 @@ TRACE_EVENT(rpc_socket_nospace,  		__entry->remaining = rqst->rq_slen - transport->xmit.offset;  	), -	TP_printk("task:%u@%u total=%u remaining=%u", +	TP_printk(SUNRPC_TRACE_TASK_SPECIFIER +		  " total=%u remaining=%u",  		__entry->task_id, __entry->client_id,  		__entry->total, __entry->remaining  	) @@ -925,18 +938,18 @@ TRACE_EVENT(rpc_socket_nospace,  #define rpc_show_xprt_state(x)						\  	__print_flags(x, "|",						\ -		{ (1UL << XPRT_LOCKED),		"LOCKED"},		\ -		{ (1UL << XPRT_CONNECTED),	"CONNECTED"},		\ -		{ (1UL << XPRT_CONNECTING),	"CONNECTING"},		\ -		{ (1UL << XPRT_CLOSE_WAIT),	"CLOSE_WAIT"},		\ -		{ (1UL << XPRT_BOUND),		"BOUND"},		\ -		{ (1UL << XPRT_BINDING),	"BINDING"},		\ -		{ (1UL << XPRT_CLOSING),	"CLOSING"},		\ -		{ (1UL << XPRT_OFFLINE),	"OFFLINE"},		\ -		{ (1UL << XPRT_REMOVE),		"REMOVE"},		\ -		{ (1UL << XPRT_CONGESTED),	"CONGESTED"},		\ -		{ (1UL << XPRT_CWND_WAIT),	"CWND_WAIT"},		\ -		{ (1UL << XPRT_WRITE_SPACE),	"WRITE_SPACE"}) +		{ BIT(XPRT_LOCKED),		"LOCKED" },		\ +		{ BIT(XPRT_CONNECTED),		"CONNECTED" },		\ +		{ BIT(XPRT_CONNECTING),		"CONNECTING" },		\ +		{ BIT(XPRT_CLOSE_WAIT),		"CLOSE_WAIT" },		\ +		{ BIT(XPRT_BOUND),		"BOUND" },		\ +		{ BIT(XPRT_BINDING),		"BINDING" },		\ +		{ BIT(XPRT_CLOSING),		"CLOSING" },		\ +		{ BIT(XPRT_OFFLINE),		"OFFLINE" },		\ +		{ BIT(XPRT_REMOVE),		"REMOVE" },		\ +		{ BIT(XPRT_CONGESTED),		"CONGESTED" },		\ +		{ BIT(XPRT_CWND_WAIT),		"CWND_WAIT" },		\ +		{ BIT(XPRT_WRITE_SPACE),	"WRITE_SPACE" })  DECLARE_EVENT_CLASS(rpc_xprt_lifetime_class,  	TP_PROTO( @@ -1042,8 +1055,8 @@ TRACE_EVENT(xprt_transmit,  		__entry->status = status;  	), -	TP_printk( -		"task:%u@%u xid=0x%08x seqno=%u status=%d", +	TP_printk(SUNRPC_TRACE_TASK_SPECIFIER +		  " xid=0x%08x seqno=%u status=%d",  		__entry->task_id, __entry->client_id, __entry->xid,  		__entry->seqno, __entry->status)  ); @@ -1082,8 +1095,8 @@ TRACE_EVENT(xprt_retransmit,  		__assign_str(procname, rpc_proc_name(task));  	), -	TP_printk( -		"task:%u@%u xid=0x%08x %sv%d %s ntrans=%d timeout=%lu", +	TP_printk(SUNRPC_TRACE_TASK_SPECIFIER +		  " xid=0x%08x %sv%d %s ntrans=%d timeout=%lu",  		__entry->task_id, __entry->client_id, __entry->xid,  		__get_str(progname), __entry->version, __get_str(procname),  		__entry->ntrans, __entry->timeout @@ -1137,7 +1150,8 @@ DECLARE_EVENT_CLASS(xprt_writelock_event,  					xprt->snd_task->tk_pid : -1;  	), -	TP_printk("task:%u@%u snd_task:%u", +	TP_printk(SUNRPC_TRACE_TASK_SPECIFIER +		  " snd_task:" SUNRPC_TRACE_PID_SPECIFIER,  			__entry->task_id, __entry->client_id,  			__entry->snd_task_id)  ); @@ -1185,7 +1199,9 @@ DECLARE_EVENT_CLASS(xprt_cong_event,  		__entry->wait = test_bit(XPRT_CWND_WAIT, &xprt->state);  	), -	TP_printk("task:%u@%u snd_task:%u cong=%lu cwnd=%lu%s", +	TP_printk(SUNRPC_TRACE_TASK_SPECIFIER +		  " snd_task:" SUNRPC_TRACE_PID_SPECIFIER +		  " cong=%lu cwnd=%lu%s",  			__entry->task_id, __entry->client_id,  			__entry->snd_task_id, __entry->cong, __entry->cwnd,  			__entry->wait ? " (wait)" : "") @@ -1223,7 +1239,7 @@ TRACE_EVENT(xprt_reserve,  		__entry->xid = be32_to_cpu(rqst->rq_xid);  	), -	TP_printk("task:%u@%u xid=0x%08x", +	TP_printk(SUNRPC_TRACE_TASK_SPECIFIER " xid=0x%08x",  		__entry->task_id, __entry->client_id, __entry->xid  	)  ); @@ -1312,7 +1328,8 @@ TRACE_EVENT(rpcb_getport,  		__assign_str(servername, task->tk_xprt->servername);  	), -	TP_printk("task:%u@%u server=%s program=%u version=%u protocol=%d bind_version=%u", +	TP_printk(SUNRPC_TRACE_TASK_SPECIFIER +		  " server=%s program=%u version=%u protocol=%d bind_version=%u",  		__entry->task_id, __entry->client_id, __get_str(servername),  		__entry->program, __entry->version, __entry->protocol,  		__entry->bind_version @@ -1342,7 +1359,7 @@ TRACE_EVENT(rpcb_setport,  		__entry->port = port;  	), -	TP_printk("task:%u@%u status=%d port=%u", +	TP_printk(SUNRPC_TRACE_TASK_SPECIFIER " status=%d port=%u",  		__entry->task_id, __entry->client_id,  		__entry->status, __entry->port  	) diff --git a/include/trace/events/sunrpc_base.h b/include/trace/events/sunrpc_base.h new file mode 100644 index 000000000000..588557d07ea8 --- /dev/null +++ b/include/trace/events/sunrpc_base.h @@ -0,0 +1,18 @@ +/* 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 */ diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index f056ff931444..a312ea2bc440 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -1076,24 +1076,21 @@ void rpc_task_set_transport(struct rpc_task *task, struct rpc_clnt *clnt)  static  void rpc_task_set_client(struct rpc_task *task, struct rpc_clnt *clnt)  { - -	if (clnt != NULL) { -		rpc_task_set_transport(task, clnt); -		task->tk_client = clnt; -		refcount_inc(&clnt->cl_count); -		if (clnt->cl_softrtry) -			task->tk_flags |= RPC_TASK_SOFT; -		if (clnt->cl_softerr) -			task->tk_flags |= RPC_TASK_TIMEOUT; -		if (clnt->cl_noretranstimeo) -			task->tk_flags |= RPC_TASK_NO_RETRANS_TIMEOUT; -		if (atomic_read(&clnt->cl_swapper)) -			task->tk_flags |= RPC_TASK_SWAPPER; -		/* Add to the client's list of all tasks */ -		spin_lock(&clnt->cl_lock); -		list_add_tail(&task->tk_task, &clnt->cl_tasks); -		spin_unlock(&clnt->cl_lock); -	} +	rpc_task_set_transport(task, clnt); +	task->tk_client = clnt; +	refcount_inc(&clnt->cl_count); +	if (clnt->cl_softrtry) +		task->tk_flags |= RPC_TASK_SOFT; +	if (clnt->cl_softerr) +		task->tk_flags |= RPC_TASK_TIMEOUT; +	if (clnt->cl_noretranstimeo) +		task->tk_flags |= RPC_TASK_NO_RETRANS_TIMEOUT; +	if (atomic_read(&clnt->cl_swapper)) +		task->tk_flags |= RPC_TASK_SWAPPER; +	/* Add to the client's list of all tasks */ +	spin_lock(&clnt->cl_lock); +	list_add_tail(&task->tk_task, &clnt->cl_tasks); +	spin_unlock(&clnt->cl_lock);  }  static void diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c index c045f63d11fa..e2c835482791 100644 --- a/net/sunrpc/sched.c +++ b/net/sunrpc/sched.c @@ -277,9 +277,17 @@ static int rpc_wait_bit_killable(struct wait_bit_key *key, int mode)  #if IS_ENABLED(CONFIG_SUNRPC_DEBUG) || IS_ENABLED(CONFIG_TRACEPOINTS)  static void rpc_task_set_debuginfo(struct rpc_task *task)  { -	static atomic_t rpc_pid; +	struct rpc_clnt *clnt = task->tk_client; -	task->tk_pid = atomic_inc_return(&rpc_pid); +	/* Might be a task carrying a reverse-direction operation */ +	if (!clnt) { +		static atomic_t rpc_pid; + +		task->tk_pid = atomic_inc_return(&rpc_pid); +		return; +	} + +	task->tk_pid = atomic_inc_return(&clnt->cl_pid);  }  #else  static inline void rpc_task_set_debuginfo(struct rpc_task *task) @@ -829,6 +837,7 @@ void rpc_exit_task(struct rpc_task *task)  	else if (task->tk_client)  		rpc_count_iostats(task, task->tk_client->cl_metrics);  	if (task->tk_ops->rpc_call_done != NULL) { +		trace_rpc_task_call_done(task, task->tk_ops->rpc_call_done);  		task->tk_ops->rpc_call_done(task, task->tk_calldata);  		if (task->tk_action != NULL) {  			/* Always release the RPC slot and buffer memory */ @@ -903,8 +912,10 @@ static void __rpc_execute(struct rpc_task *task)  		/*  		 * Lockless check for whether task is sleeping or not.  		 */ -		if (!RPC_IS_QUEUED(task)) +		if (!RPC_IS_QUEUED(task)) { +			cond_resched();  			continue; +		}  		/*  		 * Signalled tasks should exit rather than sleep. @@ -1230,8 +1241,7 @@ static int rpciod_start(void)  	if (!wq)  		goto out_failed;  	rpciod_workqueue = wq; -	/* Note: highpri because network receive is latency sensitive */ -	wq = alloc_workqueue("xprtiod", WQ_UNBOUND|WQ_MEM_RECLAIM|WQ_HIGHPRI, 0); +	wq = alloc_workqueue("xprtiod", WQ_UNBOUND | WQ_MEM_RECLAIM, 0);  	if (!wq)  		goto free_rpciod;  	xprtiod_workqueue = wq; diff --git a/net/sunrpc/sysfs.c b/net/sunrpc/sysfs.c index 9a6f17e18f73..2766dd21935b 100644 --- a/net/sunrpc/sysfs.c +++ b/net/sunrpc/sysfs.c @@ -109,8 +109,10 @@ static ssize_t rpc_sysfs_xprt_srcaddr_show(struct kobject *kobj,  	struct sock_xprt *sock;  	ssize_t ret = -1; -	if (!xprt) -		return 0; +	if (!xprt || !xprt_connected(xprt)) { +		xprt_put(xprt); +		return -ENOTCONN; +	}  	sock = container_of(xprt, struct sock_xprt, xprt);  	if (kernel_getsockname(sock->sock, (struct sockaddr *)&saddr) < 0) @@ -129,8 +131,10 @@ static ssize_t rpc_sysfs_xprt_info_show(struct kobject *kobj,  	struct rpc_xprt *xprt = rpc_sysfs_xprt_kobj_get_xprt(kobj);  	ssize_t ret; -	if (!xprt) -		return 0; +	if (!xprt || !xprt_connected(xprt)) { +		xprt_put(xprt); +		return -ENOTCONN; +	}  	ret = sprintf(buf, "last_used=%lu\ncur_cong=%lu\ncong_win=%lu\n"  		       "max_num_slots=%u\nmin_num_slots=%u\nnum_reqs=%u\n" diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index cfd681700d1a..a02de2bddb28 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c @@ -246,11 +246,9 @@ EXPORT_SYMBOL_GPL(xprt_find_transport_ident);  static void xprt_clear_locked(struct rpc_xprt *xprt)  {  	xprt->snd_task = NULL; -	if (!test_bit(XPRT_CLOSE_WAIT, &xprt->state)) { -		smp_mb__before_atomic(); -		clear_bit(XPRT_LOCKED, &xprt->state); -		smp_mb__after_atomic(); -	} else +	if (!test_bit(XPRT_CLOSE_WAIT, &xprt->state)) +		clear_bit_unlock(XPRT_LOCKED, &xprt->state); +	else  		queue_work(xprtiod_workqueue, &xprt->task_cleanup);  } @@ -737,6 +735,8 @@ static void xprt_autoclose(struct work_struct *work)  	unsigned int pflags = memalloc_nofs_save();  	trace_xprt_disconnect_auto(xprt); +	xprt->connect_cookie++; +	smp_mb__before_atomic();  	clear_bit(XPRT_CLOSE_WAIT, &xprt->state);  	xprt->ops->close(xprt);  	xprt_release_write(xprt, NULL); @@ -767,7 +767,8 @@ EXPORT_SYMBOL_GPL(xprt_disconnect_done);   */  static void xprt_schedule_autoclose_locked(struct rpc_xprt *xprt)  { -	set_bit(XPRT_CLOSE_WAIT, &xprt->state); +	if (test_and_set_bit(XPRT_CLOSE_WAIT, &xprt->state)) +		return;  	if (test_and_set_bit(XPRT_LOCKED, &xprt->state) == 0)  		queue_work(xprtiod_workqueue, &xprt->task_cleanup);  	else if (xprt->snd_task && !test_bit(XPRT_SND_IS_COOKIE, &xprt->state)) @@ -1603,15 +1604,14 @@ xprt_transmit(struct rpc_task *task)  {  	struct rpc_rqst *next, *req = task->tk_rqstp;  	struct rpc_xprt	*xprt = req->rq_xprt; -	int counter, status; +	int status;  	spin_lock(&xprt->queue_lock); -	counter = 0; -	while (!list_empty(&xprt->xmit_queue)) { -		if (++counter == 20) +	for (;;) { +		next = list_first_entry_or_null(&xprt->xmit_queue, +						struct rpc_rqst, rq_xmit); +		if (!next)  			break; -		next = list_first_entry(&xprt->xmit_queue, -				struct rpc_rqst, rq_xmit);  		xprt_pin_rqst(next);  		spin_unlock(&xprt->queue_lock);  		status = xprt_request_transmit(next, task); @@ -1619,13 +1619,16 @@ xprt_transmit(struct rpc_task *task)  			status = 0;  		spin_lock(&xprt->queue_lock);  		xprt_unpin_rqst(next); -		if (status == 0) { -			if (!xprt_request_data_received(task) || -			    test_bit(RPC_TASK_NEED_XMIT, &task->tk_runstate)) -				continue; -		} else if (test_bit(RPC_TASK_NEED_XMIT, &task->tk_runstate)) -			task->tk_status = status; -		break; +		if (status < 0) { +			if (test_bit(RPC_TASK_NEED_XMIT, &task->tk_runstate)) +				task->tk_status = status; +			break; +		} +		/* Was @task transmitted, and has it received a reply? */ +		if (xprt_request_data_received(task) && +		    !test_bit(RPC_TASK_NEED_XMIT, &task->tk_runstate)) +			break; +		cond_resched_lock(&xprt->queue_lock);  	}  	spin_unlock(&xprt->queue_lock);  } diff --git a/net/sunrpc/xprtrdma/frwr_ops.c b/net/sunrpc/xprtrdma/frwr_ops.c index f700b34a5bfd..ff699307e820 100644 --- a/net/sunrpc/xprtrdma/frwr_ops.c +++ b/net/sunrpc/xprtrdma/frwr_ops.c @@ -515,8 +515,8 @@ void frwr_unmap_sync(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req)  	 * a single ib_post_send() call.  	 */  	prev = &first; -	while ((mr = rpcrdma_mr_pop(&req->rl_registered))) { - +	mr = rpcrdma_mr_pop(&req->rl_registered); +	do {  		trace_xprtrdma_mr_localinv(mr);  		r_xprt->rx_stats.local_inv_needed++; @@ -533,7 +533,8 @@ void frwr_unmap_sync(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req)  		*prev = last;  		prev = &last->next; -	} +	} while ((mr = rpcrdma_mr_pop(&req->rl_registered))); +  	mr = container_of(last, struct rpcrdma_mr, mr_invwr);  	/* Strong send queue ordering guarantees that when the @@ -617,8 +618,8 @@ void frwr_unmap_async(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req)  	 * a single ib_post_send() call.  	 */  	prev = &first; -	while ((mr = rpcrdma_mr_pop(&req->rl_registered))) { - +	mr = rpcrdma_mr_pop(&req->rl_registered); +	do {  		trace_xprtrdma_mr_localinv(mr);  		r_xprt->rx_stats.local_inv_needed++; @@ -635,7 +636,7 @@ void frwr_unmap_async(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req)  		*prev = last;  		prev = &last->next; -	} +	} while ((mr = rpcrdma_mr_pop(&req->rl_registered)));  	/* Strong send queue ordering guarantees that when the  	 * last WR in the chain completes, all WRs in the chain @@ -666,3 +667,38 @@ void frwr_unmap_async(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req)  	 */  	rpcrdma_force_disconnect(ep);  } + +/** + * frwr_wp_create - Create an MR for padding Write chunks + * @r_xprt: transport resources to use + * + * Return 0 on success, negative errno on failure. + */ +int frwr_wp_create(struct rpcrdma_xprt *r_xprt) +{ +	struct rpcrdma_ep *ep = r_xprt->rx_ep; +	struct rpcrdma_mr_seg seg; +	struct rpcrdma_mr *mr; + +	mr = rpcrdma_mr_get(r_xprt); +	if (!mr) +		return -EAGAIN; +	mr->mr_req = NULL; +	ep->re_write_pad_mr = mr; + +	seg.mr_len = XDR_UNIT; +	seg.mr_page = virt_to_page(ep->re_write_pad); +	seg.mr_offset = offset_in_page(ep->re_write_pad); +	if (IS_ERR(frwr_map(r_xprt, &seg, 1, true, xdr_zero, mr))) +		return -EIO; +	trace_xprtrdma_mr_fastreg(mr); + +	mr->mr_cqe.done = frwr_wc_fastreg; +	mr->mr_regwr.wr.next = NULL; +	mr->mr_regwr.wr.wr_cqe = &mr->mr_cqe; +	mr->mr_regwr.wr.num_sge = 0; +	mr->mr_regwr.wr.opcode = IB_WR_REG_MR; +	mr->mr_regwr.wr.send_flags = 0; + +	return ib_post_send(ep->re_id->qp, &mr->mr_regwr.wr, NULL); +} diff --git a/net/sunrpc/xprtrdma/rpc_rdma.c b/net/sunrpc/xprtrdma/rpc_rdma.c index c335c1361564..8035a983c8ce 100644 --- a/net/sunrpc/xprtrdma/rpc_rdma.c +++ b/net/sunrpc/xprtrdma/rpc_rdma.c @@ -255,15 +255,7 @@ rpcrdma_convert_iovs(struct rpcrdma_xprt *r_xprt, struct xdr_buf *xdrbuf,  		page_base = 0;  	} -	if (type == rpcrdma_readch) -		goto out; - -	/* When encoding a Write chunk, some servers need to see an -	 * extra segment for non-XDR-aligned Write chunks. The upper -	 * layer provides space in the tail iovec that may be used -	 * for this purpose. -	 */ -	if (type == rpcrdma_writech && r_xprt->rx_ep->re_implicit_roundup) +	if (type == rpcrdma_readch || type == rpcrdma_writech)  		goto out;  	if (xdrbuf->tail[0].iov_len) @@ -405,6 +397,7 @@ static int rpcrdma_encode_write_list(struct rpcrdma_xprt *r_xprt,  				     enum rpcrdma_chunktype wtype)  {  	struct xdr_stream *xdr = &req->rl_stream; +	struct rpcrdma_ep *ep = r_xprt->rx_ep;  	struct rpcrdma_mr_seg *seg;  	struct rpcrdma_mr *mr;  	int nsegs, nchunks; @@ -443,6 +436,18 @@ static int rpcrdma_encode_write_list(struct rpcrdma_xprt *r_xprt,  		nsegs -= mr->mr_nents;  	} while (nsegs); +	if (xdr_pad_size(rqst->rq_rcv_buf.page_len)) { +		if (encode_rdma_segment(xdr, ep->re_write_pad_mr) < 0) +			return -EMSGSIZE; + +		trace_xprtrdma_chunk_wp(rqst->rq_task, ep->re_write_pad_mr, +					nsegs); +		r_xprt->rx_stats.write_chunk_count++; +		r_xprt->rx_stats.total_rdma_request += mr->mr_length; +		nchunks++; +		nsegs -= mr->mr_nents; +	} +  	/* Update count of segments in this Write chunk */  	*segcount = cpu_to_be32(nchunks); diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c index aaec3c9be8db..3d3673ba9e1e 100644 --- a/net/sunrpc/xprtrdma/verbs.c +++ b/net/sunrpc/xprtrdma/verbs.c @@ -205,14 +205,12 @@ static void rpcrdma_update_cm_private(struct rpcrdma_ep *ep,  	unsigned int rsize, wsize;  	/* Default settings for RPC-over-RDMA Version One */ -	ep->re_implicit_roundup = xprt_rdma_pad_optimize;  	rsize = RPCRDMA_V1_DEF_INLINE_SIZE;  	wsize = RPCRDMA_V1_DEF_INLINE_SIZE;  	if (pmsg &&  	    pmsg->cp_magic == rpcrdma_cmp_magic &&  	    pmsg->cp_version == RPCRDMA_CMP_VERSION) { -		ep->re_implicit_roundup = true;  		rsize = rpcrdma_decode_buffer_size(pmsg->cp_send_size);  		wsize = rpcrdma_decode_buffer_size(pmsg->cp_recv_size);  	} @@ -551,6 +549,7 @@ int rpcrdma_xprt_connect(struct rpcrdma_xprt *r_xprt)  		goto out;  	}  	rpcrdma_mrs_create(r_xprt); +	frwr_wp_create(r_xprt);  out:  	trace_xprtrdma_connect(r_xprt, rc); diff --git a/net/sunrpc/xprtrdma/xprt_rdma.h b/net/sunrpc/xprtrdma/xprt_rdma.h index d91f54eae00b..c79f92eeda76 100644 --- a/net/sunrpc/xprtrdma/xprt_rdma.h +++ b/net/sunrpc/xprtrdma/xprt_rdma.h @@ -68,13 +68,14 @@  /*   * RDMA Endpoint -- connection endpoint details   */ +struct rpcrdma_mr;  struct rpcrdma_ep {  	struct kref		re_kref;  	struct rdma_cm_id 	*re_id;  	struct ib_pd		*re_pd;  	unsigned int		re_max_rdma_segs;  	unsigned int		re_max_fr_depth; -	bool			re_implicit_roundup; +	struct rpcrdma_mr	*re_write_pad_mr;  	enum ib_mr_type		re_mrtype;  	struct completion	re_done;  	unsigned int		re_send_count; @@ -97,6 +98,8 @@ struct rpcrdma_ep {  	unsigned int		re_inline_recv;	/* negotiated */  	atomic_t		re_completion_ids; + +	char			re_write_pad[XDR_UNIT];  };  /* Pre-allocate extra Work Requests for handling reverse-direction @@ -535,6 +538,7 @@ int frwr_send(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req);  void frwr_reminv(struct rpcrdma_rep *rep, struct list_head *mrs);  void frwr_unmap_sync(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req);  void frwr_unmap_async(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req); +int frwr_wp_create(struct rpcrdma_xprt *r_xprt);  /*   * RPC/RDMA protocol calls - xprtrdma/rpc_rdma.c diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 04f1b78bcbca..ae48c9c84ee1 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c @@ -1134,6 +1134,7 @@ static void xs_run_error_worker(struct sock_xprt *transport, unsigned int nr)  static void xs_sock_reset_connection_flags(struct rpc_xprt *xprt)  { +	xprt->connect_cookie++;  	smp_mb__before_atomic();  	clear_bit(XPRT_CLOSE_WAIT, &xprt->state);  	clear_bit(XPRT_CLOSING, &xprt->state); @@ -1153,14 +1154,13 @@ static void xs_error_report(struct sock *sk)  	struct sock_xprt *transport;  	struct rpc_xprt *xprt; -	read_lock_bh(&sk->sk_callback_lock);  	if (!(xprt = xprt_from_sock(sk))) -		goto out; +		return;  	transport = container_of(xprt, struct sock_xprt, xprt);  	transport->xprt_err = -sk->sk_err;  	if (transport->xprt_err == 0) -		goto out; +		return;  	dprintk("RPC:       xs_error_report client %p, error=%d...\n",  			xprt, -transport->xprt_err);  	trace_rpc_socket_error(xprt, sk->sk_socket, transport->xprt_err); @@ -1168,8 +1168,6 @@ static void xs_error_report(struct sock *sk)  	/* barrier ensures xprt_err is set before XPRT_SOCK_WAKE_ERROR */  	smp_mb__before_atomic();  	xs_run_error_worker(transport, XPRT_SOCK_WAKE_ERROR); - out: -	read_unlock_bh(&sk->sk_callback_lock);  }  static void xs_reset_transport(struct sock_xprt *transport) @@ -1188,7 +1186,7 @@ static void xs_reset_transport(struct sock_xprt *transport)  	kernel_sock_shutdown(sock, SHUT_RDWR);  	mutex_lock(&transport->recv_mutex); -	write_lock_bh(&sk->sk_callback_lock); +	lock_sock(sk);  	transport->inet = NULL;  	transport->sock = NULL;  	transport->file = NULL; @@ -1197,10 +1195,10 @@ static void xs_reset_transport(struct sock_xprt *transport)  	xs_restore_old_callbacks(transport, sk);  	xprt_clear_connected(xprt); -	write_unlock_bh(&sk->sk_callback_lock);  	xs_sock_reset_connection_flags(xprt);  	/* Reset stream record info */  	xs_stream_reset_connect(transport); +	release_sock(sk);  	mutex_unlock(&transport->recv_mutex);  	trace_rpc_socket_close(xprt, sock); @@ -1364,7 +1362,6 @@ static void xs_data_ready(struct sock *sk)  {  	struct rpc_xprt *xprt; -	read_lock_bh(&sk->sk_callback_lock);  	dprintk("RPC:       xs_data_ready...\n");  	xprt = xprt_from_sock(sk);  	if (xprt != NULL) { @@ -1379,7 +1376,6 @@ static void xs_data_ready(struct sock *sk)  		if (!test_and_set_bit(XPRT_SOCK_DATA_READY, &transport->sock_state))  			queue_work(xprtiod_workqueue, &transport->recv_worker);  	} -	read_unlock_bh(&sk->sk_callback_lock);  }  /* @@ -1408,9 +1404,8 @@ static void xs_tcp_state_change(struct sock *sk)  	struct rpc_xprt *xprt;  	struct sock_xprt *transport; -	read_lock_bh(&sk->sk_callback_lock);  	if (!(xprt = xprt_from_sock(sk))) -		goto out; +		return;  	dprintk("RPC:       xs_tcp_state_change client %p...\n", xprt);  	dprintk("RPC:       state %x conn %d dead %d zapped %d sk_shutdown %d\n",  			sk->sk_state, xprt_connected(xprt), @@ -1471,8 +1466,6 @@ static void xs_tcp_state_change(struct sock *sk)  		/* Trigger the socket release */  		xs_run_error_worker(transport, XPRT_SOCK_WAKE_DISCONNECT);  	} - out: -	read_unlock_bh(&sk->sk_callback_lock);  }  static void xs_write_space(struct sock *sk) @@ -1511,13 +1504,9 @@ out:   */  static void xs_udp_write_space(struct sock *sk)  { -	read_lock_bh(&sk->sk_callback_lock); -  	/* from net/core/sock.c:sock_def_write_space */  	if (sock_writeable(sk))  		xs_write_space(sk); - -	read_unlock_bh(&sk->sk_callback_lock);  }  /** @@ -1532,13 +1521,9 @@ static void xs_udp_write_space(struct sock *sk)   */  static void xs_tcp_write_space(struct sock *sk)  { -	read_lock_bh(&sk->sk_callback_lock); -  	/* from net/core/stream.c:sk_stream_write_space */  	if (sk_stream_is_writeable(sk))  		xs_write_space(sk); - -	read_unlock_bh(&sk->sk_callback_lock);  }  static void xs_udp_do_set_buffer_size(struct rpc_xprt *xprt) @@ -1833,7 +1818,7 @@ static int xs_local_finish_connecting(struct rpc_xprt *xprt,  	if (!transport->inet) {  		struct sock *sk = sock->sk; -		write_lock_bh(&sk->sk_callback_lock); +		lock_sock(sk);  		xs_save_old_callbacks(transport, sk); @@ -1849,7 +1834,7 @@ static int xs_local_finish_connecting(struct rpc_xprt *xprt,  		transport->sock = sock;  		transport->inet = sk; -		write_unlock_bh(&sk->sk_callback_lock); +		release_sock(sk);  	}  	xs_stream_start_connect(transport); @@ -2031,7 +2016,7 @@ static void xs_udp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock)  	if (!transport->inet) {  		struct sock *sk = sock->sk; -		write_lock_bh(&sk->sk_callback_lock); +		lock_sock(sk);  		xs_save_old_callbacks(transport, sk); @@ -2048,7 +2033,7 @@ static void xs_udp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock)  		xs_set_memalloc(xprt); -		write_unlock_bh(&sk->sk_callback_lock); +		release_sock(sk);  	}  	xs_udp_do_set_buffer_size(xprt); @@ -2174,7 +2159,6 @@ static void xs_tcp_set_connect_timeout(struct rpc_xprt *xprt,  static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock)  {  	struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); -	int ret = -ENOTCONN;  	if (!transport->inet) {  		struct sock *sk = sock->sk; @@ -2194,7 +2178,7 @@ static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock)  		xs_tcp_set_socket_timeouts(xprt, sock);  		tcp_sock_set_nodelay(sk); -		write_lock_bh(&sk->sk_callback_lock); +		lock_sock(sk);  		xs_save_old_callbacks(transport, sk); @@ -2214,11 +2198,11 @@ static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock)  		transport->sock = sock;  		transport->inet = sk; -		write_unlock_bh(&sk->sk_callback_lock); +		release_sock(sk);  	}  	if (!xprt_bound(xprt)) -		goto out; +		return -ENOTCONN;  	xs_set_memalloc(xprt); @@ -2226,22 +2210,7 @@ static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock)  	/* Tell the socket layer to start connecting... */  	set_bit(XPRT_SOCK_CONNECTING, &transport->sock_state); -	ret = kernel_connect(sock, xs_addr(xprt), xprt->addrlen, O_NONBLOCK); -	switch (ret) { -	case 0: -		xs_set_srcport(transport, sock); -		fallthrough; -	case -EINPROGRESS: -		/* SYN_SENT! */ -		if (xprt->reestablish_timeout < XS_TCP_INIT_REEST_TO) -			xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO; -		break; -	case -EADDRNOTAVAIL: -		/* Source port number is unavailable. Try a new one! */ -		transport->srcport = 0; -	} -out: -	return ret; +	return kernel_connect(sock, xs_addr(xprt), xprt->addrlen, O_NONBLOCK);  }  /** @@ -2256,14 +2225,14 @@ static void xs_tcp_setup_socket(struct work_struct *work)  		container_of(work, struct sock_xprt, connect_worker.work);  	struct socket *sock = transport->sock;  	struct rpc_xprt *xprt = &transport->xprt; -	int status = -EIO; +	int status;  	if (!sock) {  		sock = xs_create_sock(xprt, transport,  				xs_addr(xprt)->sa_family, SOCK_STREAM,  				IPPROTO_TCP, true);  		if (IS_ERR(sock)) { -			status = PTR_ERR(sock); +			xprt_wake_pending_tasks(xprt, PTR_ERR(sock));  			goto out;  		}  	} @@ -2280,21 +2249,21 @@ static void xs_tcp_setup_socket(struct work_struct *work)  			xprt, -status, xprt_connected(xprt),  			sock->sk->sk_state);  	switch (status) { -	default: -		printk("%s: connect returned unhandled error %d\n", -			__func__, status); -		fallthrough; -	case -EADDRNOTAVAIL: -		/* We're probably in TIME_WAIT. Get rid of existing socket, -		 * and retry -		 */ -		xs_tcp_force_close(xprt); -		break;  	case 0: +		xs_set_srcport(transport, sock); +		fallthrough;  	case -EINPROGRESS: +		/* SYN_SENT! */ +		if (xprt->reestablish_timeout < XS_TCP_INIT_REEST_TO) +			xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO; +		fallthrough;  	case -EALREADY: -		xprt_unlock_connect(xprt, transport); -		return; +		goto out_unlock; +	case -EADDRNOTAVAIL: +		/* Source port number is unavailable. Try a new one! */ +		transport->srcport = 0; +		status = -EAGAIN; +		break;  	case -EINVAL:  		/* Happens, for instance, if the user specified a link  		 * local IPv6 address without a scope-id. @@ -2306,18 +2275,22 @@ static void xs_tcp_setup_socket(struct work_struct *work)  	case -EHOSTUNREACH:  	case -EADDRINUSE:  	case -ENOBUFS: -		/* xs_tcp_force_close() wakes tasks with a fixed error code. -		 * We need to wake them first to ensure the correct error code. -		 */ -		xprt_wake_pending_tasks(xprt, status); -		xs_tcp_force_close(xprt); -		goto out; +		break; +	default: +		printk("%s: connect returned unhandled error %d\n", +			__func__, status); +		status = -EAGAIN;  	} -	status = -EAGAIN; + +	/* xs_tcp_force_close() wakes tasks with a fixed error code. +	 * We need to wake them first to ensure the correct error code. +	 */ +	xprt_wake_pending_tasks(xprt, status); +	xs_tcp_force_close(xprt);  out:  	xprt_clear_connecting(xprt); +out_unlock:  	xprt_unlock_connect(xprt, transport); -	xprt_wake_pending_tasks(xprt, status);  }  /** @@ -2341,7 +2314,7 @@ static void xs_connect(struct rpc_xprt *xprt, struct rpc_task *task)  	WARN_ON_ONCE(!xprt_lock_connect(xprt, task, transport)); -	if (transport->sock != NULL) { +	if (transport->sock != NULL && !xprt_connecting(xprt)) {  		dprintk("RPC:       xs_connect delayed xprt %p for %lu "  				"seconds\n",  				xprt, xprt->reestablish_timeout / HZ); |