Commit afc23feb authored by David Howells's avatar David Howells Committed by Steve French
Browse files

cifs: Add tracing for the cifs_tcon struct refcounting



Add tracing for the refcounting/lifecycle of the cifs_tcon struct, marking
different events with different labels and giving each tcon its own debug
ID so that the tracelines corresponding to individual tcons can be
distinguished.  This can be enabled with:

	echo 1 >/sys/kernel/debug/tracing/events/cifs/smb3_tcon_ref/enable

Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
Acked-by: default avatarPaulo Alcantara (Red Hat) <pc@manguebit.com>
cc: Shyam Prasad N <nspmangalore@gmail.com>
cc: linux-cifs@vger.kernel.org
cc: linux-fsdevel@vger.kernel.org
Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
parent dad80c6b
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -739,6 +739,8 @@ static void cifs_umount_begin(struct super_block *sb)

	spin_lock(&cifs_tcp_ses_lock);
	spin_lock(&tcon->tc_lock);
	trace_smb3_tcon_ref(tcon->debug_id, tcon->tc_count,
			    netfs_trace_tcon_ref_see_umount);
	if ((tcon->tc_count > 1) || (tcon->status == TID_EXITING)) {
		/* we have other mounts to same share or we have
		   already tried to umount this and woken up
+1 −0
Original line number Diff line number Diff line
@@ -1190,6 +1190,7 @@ struct cifs_fattr {
 */
struct cifs_tcon {
	struct list_head tcon_list;
	int debug_id;		/* Debugging for tracing */
	int tc_count;
	struct list_head rlist; /* reconnect list */
	spinlock_t tc_lock;  /* protect anything here that is not protected */
+4 −5
Original line number Diff line number Diff line
@@ -303,7 +303,7 @@ cifs_get_tcp_session(struct smb3_fs_context *ctx,
		     struct TCP_Server_Info *primary_server);
extern void cifs_put_tcp_session(struct TCP_Server_Info *server,
				 int from_reconnect);
extern void cifs_put_tcon(struct cifs_tcon *tcon);
extern void cifs_put_tcon(struct cifs_tcon *tcon, enum smb3_tcon_ref_trace trace);

extern void cifs_release_automount_timer(void);

@@ -530,8 +530,9 @@ extern int CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses);

extern struct cifs_ses *sesInfoAlloc(void);
extern void sesInfoFree(struct cifs_ses *);
extern struct cifs_tcon *tcon_info_alloc(bool dir_leases_enabled);
extern void tconInfoFree(struct cifs_tcon *);
extern struct cifs_tcon *tcon_info_alloc(bool dir_leases_enabled,
					 enum smb3_tcon_ref_trace trace);
extern void tconInfoFree(struct cifs_tcon *tcon, enum smb3_tcon_ref_trace trace);

extern int cifs_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server,
		   __u32 *pexpected_response_sequence_number);
@@ -721,8 +722,6 @@ static inline int cifs_create_options(struct cifs_sb_info *cifs_sb, int options)
		return options;
}

struct super_block *cifs_get_tcon_super(struct cifs_tcon *tcon);
void cifs_put_tcon_super(struct super_block *sb);
int cifs_wait_for_server_reconnect(struct TCP_Server_Info *server, bool retry);

/* Put references of @ses and its children */
+12 −9
Original line number Diff line number Diff line
@@ -1943,7 +1943,7 @@ cifs_setup_ipc(struct cifs_ses *ses, struct smb3_fs_context *ctx)
	}

	/* no need to setup directory caching on IPC share, so pass in false */
	tcon = tcon_info_alloc(false);
	tcon = tcon_info_alloc(false, netfs_trace_tcon_ref_new_ipc);
	if (tcon == NULL)
		return -ENOMEM;

@@ -1960,7 +1960,7 @@ cifs_setup_ipc(struct cifs_ses *ses, struct smb3_fs_context *ctx)

	if (rc) {
		cifs_server_dbg(VFS, "failed to connect to IPC (rc=%d)\n", rc);
		tconInfoFree(tcon);
		tconInfoFree(tcon, netfs_trace_tcon_ref_free_ipc_fail);
		goto out;
	}

@@ -2043,7 +2043,7 @@ void __cifs_put_smb_ses(struct cifs_ses *ses)
	 * files on session close, as specified in MS-SMB2 3.3.5.6 Receiving an
	 * SMB2 LOGOFF Request.
	 */
	tconInfoFree(tcon);
	tconInfoFree(tcon, netfs_trace_tcon_ref_free_ipc);
	if (do_logoff) {
		xid = get_xid();
		rc = server->ops->logoff(xid, ses);
@@ -2432,6 +2432,8 @@ cifs_find_tcon(struct cifs_ses *ses, struct smb3_fs_context *ctx)
			continue;
		}
		++tcon->tc_count;
		trace_smb3_tcon_ref(tcon->debug_id, tcon->tc_count,
				    netfs_trace_tcon_ref_get_find);
		spin_unlock(&tcon->tc_lock);
		spin_unlock(&cifs_tcp_ses_lock);
		return tcon;
@@ -2441,7 +2443,7 @@ cifs_find_tcon(struct cifs_ses *ses, struct smb3_fs_context *ctx)
}

void
cifs_put_tcon(struct cifs_tcon *tcon)
cifs_put_tcon(struct cifs_tcon *tcon, enum smb3_tcon_ref_trace trace)
{
	unsigned int xid;
	struct cifs_ses *ses;
@@ -2457,6 +2459,7 @@ cifs_put_tcon(struct cifs_tcon *tcon)
	cifs_dbg(FYI, "%s: tc_count=%d\n", __func__, tcon->tc_count);
	spin_lock(&cifs_tcp_ses_lock);
	spin_lock(&tcon->tc_lock);
	trace_smb3_tcon_ref(tcon->debug_id, tcon->tc_count - 1, trace);
	if (--tcon->tc_count > 0) {
		spin_unlock(&tcon->tc_lock);
		spin_unlock(&cifs_tcp_ses_lock);
@@ -2493,7 +2496,7 @@ cifs_put_tcon(struct cifs_tcon *tcon)
	_free_xid(xid);

	cifs_fscache_release_super_cookie(tcon);
	tconInfoFree(tcon);
	tconInfoFree(tcon, netfs_trace_tcon_ref_free);
	cifs_put_smb_ses(ses);
}

@@ -2547,7 +2550,7 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb3_fs_context *ctx)
		nohandlecache = ctx->nohandlecache;
	else
		nohandlecache = true;
	tcon = tcon_info_alloc(!nohandlecache);
	tcon = tcon_info_alloc(!nohandlecache, netfs_trace_tcon_ref_new);
	if (tcon == NULL) {
		rc = -ENOMEM;
		goto out_fail;
@@ -2737,7 +2740,7 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb3_fs_context *ctx)
	return tcon;

out_fail:
	tconInfoFree(tcon);
	tconInfoFree(tcon, netfs_trace_tcon_ref_free_fail);
	return ERR_PTR(rc);
}

@@ -2754,7 +2757,7 @@ cifs_put_tlink(struct tcon_link *tlink)
	}

	if (!IS_ERR(tlink_tcon(tlink)))
		cifs_put_tcon(tlink_tcon(tlink));
		cifs_put_tcon(tlink_tcon(tlink), netfs_trace_tcon_ref_put_tlink);
	kfree(tlink);
}

@@ -3319,7 +3322,7 @@ void cifs_mount_put_conns(struct cifs_mount_ctx *mnt_ctx)
	int rc = 0;

	if (mnt_ctx->tcon)
		cifs_put_tcon(mnt_ctx->tcon);
		cifs_put_tcon(mnt_ctx->tcon, netfs_trace_tcon_ref_put_mnt_ctx);
	else if (mnt_ctx->ses)
		cifs_put_smb_ses(mnt_ctx->ses);
	else if (mnt_ctx->server)
+7 −0
Original line number Diff line number Diff line
@@ -94,6 +94,11 @@ int cifs_fscache_get_super_cookie(struct cifs_tcon *tcon)
		}
		pr_err("Cache volume key already in use (%s)\n", key);
		vcookie = NULL;
		trace_smb3_tcon_ref(tcon->debug_id, tcon->tc_count,
				    netfs_trace_tcon_ref_see_fscache_collision);
	} else {
		trace_smb3_tcon_ref(tcon->debug_id, tcon->tc_count,
				    netfs_trace_tcon_ref_see_fscache_okay);
	}

	tcon->fscache = vcookie;
@@ -115,6 +120,8 @@ void cifs_fscache_release_super_cookie(struct cifs_tcon *tcon)
	cifs_fscache_fill_volume_coherency(tcon, &cd);
	fscache_relinquish_volume(tcon->fscache, &cd, false);
	tcon->fscache = NULL;
	trace_smb3_tcon_ref(tcon->debug_id, tcon->tc_count,
			    netfs_trace_tcon_ref_see_fscache_relinq);
}

void cifs_fscache_get_inode_cookie(struct inode *inode)
Loading