linux-cifs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* tcon and session refcounts, get/put
@ 2018-01-12 18:38 Aurélien Aptel
       [not found] ` <876086apmw.fsf-IBi9RG/b67k@public.gmane.org>
  0 siblings, 1 reply; 3+ messages in thread
From: Aurélien Aptel @ 2018-01-12 18:38 UTC (permalink / raw)
  To: linux-cifs-u79uwXL29TY76Z2rM5mHXA, Jeff Layton

Hi,

While working on a bug I've found something strange.

cifs_get_tcon(ses, volinfo) looks for a tcon matching volinfo in ses
tcon list. If it doesn't find one it create one.

Can someone explain to me why when it finds a matching one, it *puts*
the session?

static struct cifs_tcon *
cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info)
{
	int rc, xid;
	struct cifs_tcon *tcon;

	tcon = cifs_find_tcon(ses, volume_info);
	if (tcon) {
		cifs_dbg(FYI, "Found match on UNC path\n");
		/* existing tcon already has a reference */
		cifs_put_smb_ses(ses); <---- why?
		return tcon;
	}

        <... code that creates the missing tcon ...>

I think the "existing tcon already has a reference" comment refers to the
fact that cifs_find_tcon() already increments the refcount of the tcon
and so there's no need to do it a second time.

static struct cifs_tcon *
cifs_find_tcon(struct cifs_ses *ses, struct smb_vol *volume_info)
{
	struct list_head *tmp;
	struct cifs_tcon *tcon;

	spin_lock(&cifs_tcp_ses_lock);
	list_for_each(tmp, &ses->tcon_list) {
		tcon = list_entry(tmp, struct cifs_tcon, tcon_list);
		if (!match_tcon(tcon, volume_info))
			continue;
		++tcon->tc_count;
		spin_unlock(&cifs_tcp_ses_lock);
		return tcon;
	}
	spin_unlock(&cifs_tcp_ses_lock);
	return NULL;
}


I don't understand the logic here and I have a feeling it might be a
bug.

-- 
Aurélien Aptel / SUSE Labs Samba Team
GPG: 1839 CB5F 9F5B FB9B AA97  8C99 03C8 A49B 521B D5D3
SUSE Linux GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany
GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg)

^ permalink raw reply	[flat|nested] 3+ messages in thread

* RE: tcon and session refcounts, get/put
       [not found] ` <876086apmw.fsf-IBi9RG/b67k@public.gmane.org>
@ 2018-01-12 23:02   ` Pavel Shilovskiy
       [not found]     ` <DM5PR2101MB09361C20BD140B6E02B2C426B6170-uvswG4RmAWieOSyIubIsYpz2gl+EIwcenBOFsp37pqbUKgpGm//BTAC/G2K4zDHf@public.gmane.org>
  0 siblings, 1 reply; 3+ messages in thread
From: Pavel Shilovskiy @ 2018-01-12 23:02 UTC (permalink / raw)
  To: Aurélien Aptel,
	linux-cifs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Jeff Layton

2018-01-12 10:38 GMT-08:00 Aurélien Aptel <aaptel@suse.com>:
> Hi,

Hi Aurelien,

>
> While working on a bug I've found something strange.
>
> cifs_get_tcon(ses, volinfo) looks for a tcon matching volinfo in ses
> tcon list. If it doesn't find one it create one.
>
> Can someone explain to me why when it finds a matching one, it *puts*
> the session?
>
> static struct cifs_tcon *
> cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info)
> {
>         int rc, xid;
>         struct cifs_tcon *tcon;
>
>         tcon = cifs_find_tcon(ses, volume_info);
>         if (tcon) {
>                 cifs_dbg(FYI, "Found match on UNC path\n");
>                 /* existing tcon already has a reference */
>                 cifs_put_smb_ses(ses); <---- why?
>                 return tcon;
>         }
>
>         <... code that creates the missing tcon ...>
>
> I think the "existing tcon already has a reference" comment refers to the
> fact that cifs_find_tcon() already increments the refcount of the tcon
> and so there's no need to do it a second time.

Every tcon holds a reference to smb ses, every smb ses hold a reference to tcp ses. Refcount of tcp ses means a number of smb ses referencing this tcp ses. Refcount of smb ses means a number of tcon referencing this smb ses. Refcount of tcon means a number of mounts referencing the tcon.

Suppose we have 1 tcon pointing to 1 smb ses (pointing to 1 tcp ses). Before calling cifs_get_tcon() we have already obtained a reference to smb ses (which increments refcount of this smb ses to 2) and now we are trying to search for tcon that matches ours. If we found one we should increment refcount of this tcon, so, tc_count = 2.

>
> static struct cifs_tcon *
> cifs_find_tcon(struct cifs_ses *ses, struct smb_vol *volume_info)
> {
>         struct list_head *tmp;
>         struct cifs_tcon *tcon;
>
>         spin_lock(&cifs_tcp_ses_lock);
>         list_for_each(tmp, &ses->tcon_list) {
>                 tcon = list_entry(tmp, struct cifs_tcon, tcon_list);
>                 if (!match_tcon(tcon, volume_info))
>                         continue;
>                 ++tcon->tc_count;
>                 spin_unlock(&cifs_tcp_ses_lock);
>                 return tcon;
>         }
>         spin_unlock(&cifs_tcp_ses_lock);
>         return NULL;
> }

But this tcon already has its own reference to smb ses. So, our reference to smb ses is useless because we doesn't create a new tcon which should hold the reference. So, that's why we drop our reference. At the end we have 1 tcp ses referenced by 1 smb ses referenced by 1 tcon referenced by 2 mounts.

>
> I don't understand the logic here and I have a feeling it might be a
> bug.

We probably need a comment describing this behavior, so, an appropriate patch is highly welcomed.

--
Best regards,
Pavel Shilovsky

^ permalink raw reply	[flat|nested] 3+ messages in thread

* RE: tcon and session refcounts, get/put
       [not found]     ` <DM5PR2101MB09361C20BD140B6E02B2C426B6170-uvswG4RmAWieOSyIubIsYpz2gl+EIwcenBOFsp37pqbUKgpGm//BTAC/G2K4zDHf@public.gmane.org>
@ 2018-01-15 10:12       ` Aurélien Aptel
  0 siblings, 0 replies; 3+ messages in thread
From: Aurélien Aptel @ 2018-01-15 10:12 UTC (permalink / raw)
  To: Pavel Shilovskiy, linux-cifs@vger.kernel.org, Jeff Layton

Pavel Shilovskiy <pshilov-0li6OtcxBFHby3iVrkZq2A@public.gmane.org> writes:
> But this tcon already has its own reference to smb ses. So, our reference to smb ses is useless because we doesn't create a new tcon which should hold the reference. So, that's why we drop our reference. At the end we have 1 tcp ses referenced by 1 smb ses referenced by 1 tcon referenced by 2 mounts.

Much clearer now, thanks Pavel!

> We probably need a comment describing this behavior, so, an appropriate patch is highly welcomed.

I will do that.

-- 
Aurélien Aptel / SUSE Labs Samba Team
GPG: 1839 CB5F 9F5B FB9B AA97  8C99 03C8 A49B 521B D5D3
SUSE Linux GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany
GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg)

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2018-01-15 10:12 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-01-12 18:38 tcon and session refcounts, get/put Aurélien Aptel
     [not found] ` <876086apmw.fsf-IBi9RG/b67k@public.gmane.org>
2018-01-12 23:02   ` Pavel Shilovskiy
     [not found]     ` <DM5PR2101MB09361C20BD140B6E02B2C426B6170-uvswG4RmAWieOSyIubIsYpz2gl+EIwcenBOFsp37pqbUKgpGm//BTAC/G2K4zDHf@public.gmane.org>
2018-01-15 10:12       ` Aurélien Aptel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).