All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] cifs: don't leak -EAGAIN for stat() during reconnect
@ 2020-02-18  4:48 Ronnie Sahlberg
  2020-02-18 11:47 ` Aurélien Aptel
  0 siblings, 1 reply; 8+ messages in thread
From: Ronnie Sahlberg @ 2020-02-18  4:48 UTC (permalink / raw)
  To: linux-cifs; +Cc: Ronnie Sahlberg

If from cifs_revalidate_dentry_attr() the SMB2/QUERY_INFO call fails with an
error, such as STATUS_SESSION_EXPIRED, causing the session to be reconnected
it is possible we will leak -EAGAIN back to the application even for
system calls such as stat() where this is not a valid error.

Fix this by re-trying the operation from within cifs_revalidate_dentry_attr()
if cifs_get_inode_info*() returns -EAGAIN.

This fixes stat() and possibly also other system calls that uses
cifs_revalidate_dentry*().

Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
---
 fs/cifs/inode.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index b5e6635c578e..1c6f659110d0 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -2073,6 +2073,7 @@ int cifs_revalidate_dentry_attr(struct dentry *dentry)
 	struct inode *inode = d_inode(dentry);
 	struct super_block *sb = dentry->d_sb;
 	char *full_path = NULL;
+	int count = 0;
 
 	if (inode == NULL)
 		return -ENOENT;
@@ -2094,15 +2095,18 @@ int cifs_revalidate_dentry_attr(struct dentry *dentry)
 		 full_path, inode, inode->i_count.counter,
 		 dentry, cifs_get_time(dentry), jiffies);
 
+again:
 	if (cifs_sb_master_tcon(CIFS_SB(sb))->unix_ext)
 		rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid);
 	else
 		rc = cifs_get_inode_info(&inode, full_path, NULL, sb,
 					 xid, NULL);
-
+	if (rc == -EAGAIN && count++ < 10)
+		goto again;
 out:
 	kfree(full_path);
 	free_xid(xid);
+
 	return rc;
 }
 
-- 
2.13.6


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

* Re: [PATCH] cifs: don't leak -EAGAIN for stat() during reconnect
  2020-02-18  4:48 [PATCH] cifs: don't leak -EAGAIN for stat() during reconnect Ronnie Sahlberg
@ 2020-02-18 11:47 ` Aurélien Aptel
  2020-02-18 19:58   ` ronnie sahlberg
  0 siblings, 1 reply; 8+ messages in thread
From: Aurélien Aptel @ 2020-02-18 11:47 UTC (permalink / raw)
  To: Ronnie Sahlberg, linux-cifs; +Cc: Ronnie Sahlberg

Hi Ronnie,

Ronnie Sahlberg <lsahlber@redhat.com> writes:
> Fix this by re-trying the operation from within cifs_revalidate_dentry_attr()
> if cifs_get_inode_info*() returns -EAGAIN.

Would it make sense to use is_retryable_error() instead of checking for
just EAGAIN? It also checks for interruption errors.

Cheers,
-- 
Aurélien Aptel / SUSE Labs Samba Team
GPG: 1839 CB5F 9F5B FB9B AA97  8C99 03C8 A49B 521B D5D3
SUSE Software Solutions Germany GmbH, Maxfeldstr. 5, 90409 Nürnberg, DE
GF: Felix Imendörffer, Mary Higgins, Sri Rasiah HRB 247165 (AG München)

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

* Re: [PATCH] cifs: don't leak -EAGAIN for stat() during reconnect
  2020-02-18 11:47 ` Aurélien Aptel
@ 2020-02-18 19:58   ` ronnie sahlberg
  0 siblings, 0 replies; 8+ messages in thread
From: ronnie sahlberg @ 2020-02-18 19:58 UTC (permalink / raw)
  To: Aurélien Aptel; +Cc: Ronnie Sahlberg, linux-cifs

On Tue, Feb 18, 2020 at 9:47 PM Aurélien Aptel <aaptel@suse.com> wrote:
>
> Hi Ronnie,
>
> Ronnie Sahlberg <lsahlber@redhat.com> writes:
> > Fix this by re-trying the operation from within cifs_revalidate_dentry_attr()
> > if cifs_get_inode_info*() returns -EAGAIN.
>
> Would it make sense to use is_retryable_error() instead of checking for
> just EAGAIN? It also checks for interruption errors.

Makes sense. Thanks.

>
> Cheers,
> --
> Aurélien Aptel / SUSE Labs Samba Team
> GPG: 1839 CB5F 9F5B FB9B AA97  8C99 03C8 A49B 521B D5D3
> SUSE Software Solutions Germany GmbH, Maxfeldstr. 5, 90409 Nürnberg, DE
> GF: Felix Imendörffer, Mary Higgins, Sri Rasiah HRB 247165 (AG München)

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

* Re: [PATCH] cifs: don't leak -EAGAIN for stat() during reconnect
  2020-02-24 19:36   ` Pavel Shilovsky
@ 2020-02-24 20:22     ` Steve French
  0 siblings, 0 replies; 8+ messages in thread
From: Steve French @ 2020-02-24 20:22 UTC (permalink / raw)
  To: Pavel Shilovsky; +Cc: Ronnie Sahlberg, linux-cifs

[-- Attachment #1: Type: text/plain, Size: 2897 bytes --]

updated Ronnie's patch and remerged to cifs-2.6.git for-next

Let me know if any objections

On Mon, Feb 24, 2020 at 1:36 PM Pavel Shilovsky <piastryyy@gmail.com> wrote:
>
> вт, 18 февр. 2020 г. в 15:27, Steve French <smfrench@gmail.com>:
> >
> > merged into cifs-2.6.git for-next
> >
> > On Tue, Feb 18, 2020 at 2:07 PM Ronnie Sahlberg <lsahlber@redhat.com> wrote:
> > >
> > > If from cifs_revalidate_dentry_attr() the SMB2/QUERY_INFO call fails with an
> > > error, such as STATUS_SESSION_EXPIRED, causing the session to be reconnected
> > > it is possible we will leak -EAGAIN back to the application even for
> > > system calls such as stat() where this is not a valid error.
> > >
> > > Fix this by re-trying the operation from within cifs_revalidate_dentry_attr()
> > > if cifs_get_inode_info*() returns -EAGAIN.
> > >
> > > This fixes stat() and possibly also other system calls that uses
> > > cifs_revalidate_dentry*().
> > >
> > > Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
> > > ---
> > >  fs/cifs/inode.c | 6 +++++-
> > >  1 file changed, 5 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
> > > index b5e6635c578e..1212ace05258 100644
> > > --- a/fs/cifs/inode.c
> > > +++ b/fs/cifs/inode.c
> > > @@ -2073,6 +2073,7 @@ int cifs_revalidate_dentry_attr(struct dentry *dentry)
> > >         struct inode *inode = d_inode(dentry);
> > >         struct super_block *sb = dentry->d_sb;
> > >         char *full_path = NULL;
> > > +       int count = 0;
> > >
> > >         if (inode == NULL)
> > >                 return -ENOENT;
> > > @@ -2094,15 +2095,18 @@ int cifs_revalidate_dentry_attr(struct dentry *dentry)
> > >                  full_path, inode, inode->i_count.counter,
> > >                  dentry, cifs_get_time(dentry), jiffies);
> > >
> > > +again:
> > >         if (cifs_sb_master_tcon(CIFS_SB(sb))->unix_ext)
> > >                 rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid);
> > >         else
> > >                 rc = cifs_get_inode_info(&inode, full_path, NULL, sb,
> > >                                          xid, NULL);
> > > -
> > > +       if (is_retryable_error(rc) && count++ < 10)
> > > +               goto again;
>
> If there is interrupt error, you will end up doing 10 attempts with
> the same outcome - interrupt error. Such errors should be returned to
> the upper layers to be handled correctly (restart of a system call or
> return of EINTR error to the user space).
>
> Please revert to your original version that handles EAGAIN only.
>
> --
> Best regards,
> Pavel Shilovsky
>
> > >  out:
> > >         kfree(full_path);
> > >         free_xid(xid);
> > > +
> > >         return rc;
> > >  }
> > >
> > > --
> > > 2.13.6
> > >
> >
> >
> > --
> > Thanks,
> >
> > Steve



-- 
Thanks,

Steve

[-- Attachment #2: 0001-cifs-don-t-leak-EAGAIN-for-stat-during-reconnect.patch --]
[-- Type: text/x-patch, Size: 1931 bytes --]

From 9255f1c5788c0d97d0ef31b0fabb6457787ce680 Mon Sep 17 00:00:00 2001
From: Ronnie Sahlberg <lsahlber@redhat.com>
Date: Wed, 19 Feb 2020 06:01:03 +1000
Subject: [PATCH 01/10] cifs: don't leak -EAGAIN for stat() during reconnect

If from cifs_revalidate_dentry_attr() the SMB2/QUERY_INFO call fails with an
error, such as STATUS_SESSION_EXPIRED, causing the session to be reconnected
it is possible we will leak -EAGAIN back to the application even for
system calls such as stat() where this is not a valid error.

Fix this by re-trying the operation from within cifs_revalidate_dentry_attr()
if cifs_get_inode_info*() returns -EAGAIN.

This fixes stat() and possibly also other system calls that uses
cifs_revalidate_dentry*().

Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com>
Reviewed-by: Aurelien Aptel <aaptel@suse.com>
CC: Stable <stable@vger.kernel.org>
---
 fs/cifs/inode.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index b5e6635c578e..1212ace05258 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -2073,6 +2073,7 @@ int cifs_revalidate_dentry_attr(struct dentry *dentry)
 	struct inode *inode = d_inode(dentry);
 	struct super_block *sb = dentry->d_sb;
 	char *full_path = NULL;
+	int count = 0;
 
 	if (inode == NULL)
 		return -ENOENT;
@@ -2094,15 +2095,18 @@ int cifs_revalidate_dentry_attr(struct dentry *dentry)
 		 full_path, inode, inode->i_count.counter,
 		 dentry, cifs_get_time(dentry), jiffies);
 
+again:
 	if (cifs_sb_master_tcon(CIFS_SB(sb))->unix_ext)
 		rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid);
 	else
 		rc = cifs_get_inode_info(&inode, full_path, NULL, sb,
 					 xid, NULL);
-
+	if (rc == -EAGAIN && count++ < 10)
+		goto again;
 out:
 	kfree(full_path);
 	free_xid(xid);
+
 	return rc;
 }
 
-- 
2.20.1


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

* Re: [PATCH] cifs: don't leak -EAGAIN for stat() during reconnect
  2020-02-18 23:26 ` Steve French
@ 2020-02-24 19:36   ` Pavel Shilovsky
  2020-02-24 20:22     ` Steve French
  0 siblings, 1 reply; 8+ messages in thread
From: Pavel Shilovsky @ 2020-02-24 19:36 UTC (permalink / raw)
  To: Steve French; +Cc: Ronnie Sahlberg, linux-cifs

вт, 18 февр. 2020 г. в 15:27, Steve French <smfrench@gmail.com>:
>
> merged into cifs-2.6.git for-next
>
> On Tue, Feb 18, 2020 at 2:07 PM Ronnie Sahlberg <lsahlber@redhat.com> wrote:
> >
> > If from cifs_revalidate_dentry_attr() the SMB2/QUERY_INFO call fails with an
> > error, such as STATUS_SESSION_EXPIRED, causing the session to be reconnected
> > it is possible we will leak -EAGAIN back to the application even for
> > system calls such as stat() where this is not a valid error.
> >
> > Fix this by re-trying the operation from within cifs_revalidate_dentry_attr()
> > if cifs_get_inode_info*() returns -EAGAIN.
> >
> > This fixes stat() and possibly also other system calls that uses
> > cifs_revalidate_dentry*().
> >
> > Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
> > ---
> >  fs/cifs/inode.c | 6 +++++-
> >  1 file changed, 5 insertions(+), 1 deletion(-)
> >
> > diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
> > index b5e6635c578e..1212ace05258 100644
> > --- a/fs/cifs/inode.c
> > +++ b/fs/cifs/inode.c
> > @@ -2073,6 +2073,7 @@ int cifs_revalidate_dentry_attr(struct dentry *dentry)
> >         struct inode *inode = d_inode(dentry);
> >         struct super_block *sb = dentry->d_sb;
> >         char *full_path = NULL;
> > +       int count = 0;
> >
> >         if (inode == NULL)
> >                 return -ENOENT;
> > @@ -2094,15 +2095,18 @@ int cifs_revalidate_dentry_attr(struct dentry *dentry)
> >                  full_path, inode, inode->i_count.counter,
> >                  dentry, cifs_get_time(dentry), jiffies);
> >
> > +again:
> >         if (cifs_sb_master_tcon(CIFS_SB(sb))->unix_ext)
> >                 rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid);
> >         else
> >                 rc = cifs_get_inode_info(&inode, full_path, NULL, sb,
> >                                          xid, NULL);
> > -
> > +       if (is_retryable_error(rc) && count++ < 10)
> > +               goto again;

If there is interrupt error, you will end up doing 10 attempts with
the same outcome - interrupt error. Such errors should be returned to
the upper layers to be handled correctly (restart of a system call or
return of EINTR error to the user space).

Please revert to your original version that handles EAGAIN only.

--
Best regards,
Pavel Shilovsky

> >  out:
> >         kfree(full_path);
> >         free_xid(xid);
> > +
> >         return rc;
> >  }
> >
> > --
> > 2.13.6
> >
>
>
> --
> Thanks,
>
> Steve

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

* Re: [PATCH] cifs: don't leak -EAGAIN for stat() during reconnect
  2020-02-18 20:01 Ronnie Sahlberg
@ 2020-02-18 23:26 ` Steve French
  2020-02-24 19:36   ` Pavel Shilovsky
  0 siblings, 1 reply; 8+ messages in thread
From: Steve French @ 2020-02-18 23:26 UTC (permalink / raw)
  To: Ronnie Sahlberg; +Cc: linux-cifs

merged into cifs-2.6.git for-next

On Tue, Feb 18, 2020 at 2:07 PM Ronnie Sahlberg <lsahlber@redhat.com> wrote:
>
> If from cifs_revalidate_dentry_attr() the SMB2/QUERY_INFO call fails with an
> error, such as STATUS_SESSION_EXPIRED, causing the session to be reconnected
> it is possible we will leak -EAGAIN back to the application even for
> system calls such as stat() where this is not a valid error.
>
> Fix this by re-trying the operation from within cifs_revalidate_dentry_attr()
> if cifs_get_inode_info*() returns -EAGAIN.
>
> This fixes stat() and possibly also other system calls that uses
> cifs_revalidate_dentry*().
>
> Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
> ---
>  fs/cifs/inode.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
> index b5e6635c578e..1212ace05258 100644
> --- a/fs/cifs/inode.c
> +++ b/fs/cifs/inode.c
> @@ -2073,6 +2073,7 @@ int cifs_revalidate_dentry_attr(struct dentry *dentry)
>         struct inode *inode = d_inode(dentry);
>         struct super_block *sb = dentry->d_sb;
>         char *full_path = NULL;
> +       int count = 0;
>
>         if (inode == NULL)
>                 return -ENOENT;
> @@ -2094,15 +2095,18 @@ int cifs_revalidate_dentry_attr(struct dentry *dentry)
>                  full_path, inode, inode->i_count.counter,
>                  dentry, cifs_get_time(dentry), jiffies);
>
> +again:
>         if (cifs_sb_master_tcon(CIFS_SB(sb))->unix_ext)
>                 rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid);
>         else
>                 rc = cifs_get_inode_info(&inode, full_path, NULL, sb,
>                                          xid, NULL);
> -
> +       if (is_retryable_error(rc) && count++ < 10)
> +               goto again;
>  out:
>         kfree(full_path);
>         free_xid(xid);
> +
>         return rc;
>  }
>
> --
> 2.13.6
>


-- 
Thanks,

Steve

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

* [PATCH] cifs: don't leak -EAGAIN for stat() during reconnect
@ 2020-02-18 20:01 Ronnie Sahlberg
  2020-02-18 23:26 ` Steve French
  0 siblings, 1 reply; 8+ messages in thread
From: Ronnie Sahlberg @ 2020-02-18 20:01 UTC (permalink / raw)
  To: linux-cifs; +Cc: Ronnie Sahlberg

If from cifs_revalidate_dentry_attr() the SMB2/QUERY_INFO call fails with an
error, such as STATUS_SESSION_EXPIRED, causing the session to be reconnected
it is possible we will leak -EAGAIN back to the application even for
system calls such as stat() where this is not a valid error.

Fix this by re-trying the operation from within cifs_revalidate_dentry_attr()
if cifs_get_inode_info*() returns -EAGAIN.

This fixes stat() and possibly also other system calls that uses
cifs_revalidate_dentry*().

Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
---
 fs/cifs/inode.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index b5e6635c578e..1212ace05258 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -2073,6 +2073,7 @@ int cifs_revalidate_dentry_attr(struct dentry *dentry)
 	struct inode *inode = d_inode(dentry);
 	struct super_block *sb = dentry->d_sb;
 	char *full_path = NULL;
+	int count = 0;
 
 	if (inode == NULL)
 		return -ENOENT;
@@ -2094,15 +2095,18 @@ int cifs_revalidate_dentry_attr(struct dentry *dentry)
 		 full_path, inode, inode->i_count.counter,
 		 dentry, cifs_get_time(dentry), jiffies);
 
+again:
 	if (cifs_sb_master_tcon(CIFS_SB(sb))->unix_ext)
 		rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid);
 	else
 		rc = cifs_get_inode_info(&inode, full_path, NULL, sb,
 					 xid, NULL);
-
+	if (is_retryable_error(rc) && count++ < 10)
+		goto again;
 out:
 	kfree(full_path);
 	free_xid(xid);
+
 	return rc;
 }
 
-- 
2.13.6


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

* [PATCH] cifs: don't leak -EAGAIN for stat() during reconnect
  2020-02-18  4:18 [PATCH 0/1] dont leak -EAGAIN Ronnie Sahlberg
@ 2020-02-18  4:18 ` Ronnie Sahlberg
  0 siblings, 0 replies; 8+ messages in thread
From: Ronnie Sahlberg @ 2020-02-18  4:18 UTC (permalink / raw)
  To: linux-cifs; +Cc: Ronnie Sahlberg

If from cifs_revalidate_dentry_attr() the SMB2/QUERY_INFO call fails with an
error, such as STATUS_SESSION_EXPIRED, causing the session to be reconnected
it is possible we will leak -EAGAIN back to the application even for
system calls such as stat() where this is not a valid error.

Fix this by re-trying the operation from within cifs_revalidate_dentry_attr()
if cifs_get_inode_info*() returns -EAGAIN.

This fixes stat() and possibly also other system calls that uses
cifs_revalidate_dentry*().

Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
---
 fs/cifs/inode.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index b5e6635c578e..cf36dcd9dafd 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -2073,7 +2073,9 @@ int cifs_revalidate_dentry_attr(struct dentry *dentry)
 	struct inode *inode = d_inode(dentry);
 	struct super_block *sb = dentry->d_sb;
 	char *full_path = NULL;
+	int count = 0;
 
+again:
 	if (inode == NULL)
 		return -ENOENT;
 
@@ -2099,6 +2101,8 @@ int cifs_revalidate_dentry_attr(struct dentry *dentry)
 	else
 		rc = cifs_get_inode_info(&inode, full_path, NULL, sb,
 					 xid, NULL);
+	if (rc == -EAGAIN && count++ < 10)
+		goto again;
 
 out:
 	kfree(full_path);
-- 
2.13.6


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

end of thread, other threads:[~2020-02-24 20:22 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-18  4:48 [PATCH] cifs: don't leak -EAGAIN for stat() during reconnect Ronnie Sahlberg
2020-02-18 11:47 ` Aurélien Aptel
2020-02-18 19:58   ` ronnie sahlberg
  -- strict thread matches above, loose matches on Subject: below --
2020-02-18 20:01 Ronnie Sahlberg
2020-02-18 23:26 ` Steve French
2020-02-24 19:36   ` Pavel Shilovsky
2020-02-24 20:22     ` Steve French
2020-02-18  4:18 [PATCH 0/1] dont leak -EAGAIN Ronnie Sahlberg
2020-02-18  4:18 ` [PATCH] cifs: don't leak -EAGAIN for stat() during reconnect Ronnie Sahlberg

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.