From: Steve French <smfrench@gmail.com>
To: "Pavel Shilovsky" <piastryyy@gmail.com>,
"Aurélien Aptel" <aaptel@suse.com>,
"Paulo Alcantara" <paulo@paulo.ac>
Cc: Ronnie Sahlberg <lsahlber@redhat.com>,
Frank Sorenson <sorenson@redhat.com>,
linux-cifs <linux-cifs@vger.kernel.org>
Subject: Re: [PATCH 1/3] CIFS: Close open handle after interrupted close
Date: Thu, 21 Nov 2019 16:00:47 -0600 [thread overview]
Message-ID: <CAH2r5muszgyJWP6mUYs6nsHQQN-6ST63DJvyFus+STrJYP4-ug@mail.gmail.com> (raw)
In-Reply-To: <20191121193514.3086-1-pshilov@microsoft.com>
Merged these three (and one of Aurelien's recent patches for
multichannel - need updates to that, also waiting on Paulo's DFS fix)
into cifs-2.6.git for-next (and also the buildbot's gitub for-next
branch)
On Thu, Nov 21, 2019 at 1:35 PM Pavel Shilovsky <piastryyy@gmail.com> wrote:
>
> If Close command is interrupted before sending a request
> to the server the client ends up leaking an open file
> handle. This wastes server resources and can potentially
> block applications that try to remove the file or any
> directory containing this file.
>
> Fix this by putting the close command into a worker queue,
> so another thread retries it later.
>
> Cc: Stable <stable@vger.kernel.org>
> Signed-off-by: Pavel Shilovsky <pshilov@microsoft.com>
> ---
> fs/cifs/smb2misc.c | 59 ++++++++++++++++++++++++++++++++++-----------
> fs/cifs/smb2pdu.c | 16 +++++++++++-
> fs/cifs/smb2proto.h | 3 +++
> 3 files changed, 63 insertions(+), 15 deletions(-)
>
> diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c
> index 527c9efd3de0..80a8f4b2daab 100644
> --- a/fs/cifs/smb2misc.c
> +++ b/fs/cifs/smb2misc.c
> @@ -725,36 +725,67 @@ smb2_cancelled_close_fid(struct work_struct *work)
> kfree(cancelled);
> }
>
> +/* Caller should already has an extra reference to @tcon */
> +static int
> +__smb2_handle_cancelled_close(struct cifs_tcon *tcon, __u64 persistent_fid,
> + __u64 volatile_fid)
> +{
> + struct close_cancelled_open *cancelled;
> +
> + cancelled = kzalloc(sizeof(*cancelled), GFP_KERNEL);
> + if (!cancelled)
> + return -ENOMEM;
> +
> + cancelled->fid.persistent_fid = persistent_fid;
> + cancelled->fid.volatile_fid = volatile_fid;
> + cancelled->tcon = tcon;
> + INIT_WORK(&cancelled->work, smb2_cancelled_close_fid);
> + WARN_ON(queue_work(cifsiod_wq, &cancelled->work) == false);
> +
> + return 0;
> +}
> +
> +int
> +smb2_handle_cancelled_close(struct cifs_tcon *tcon, __u64 persistent_fid,
> + __u64 volatile_fid)
> +{
> + int rc;
> +
> + cifs_dbg(FYI, "%s: tc_count=%d\n", __func__, tcon->tc_count);
> + spin_lock(&cifs_tcp_ses_lock);
> + tcon->tc_count++;
> + spin_unlock(&cifs_tcp_ses_lock);
> +
> + rc = __smb2_handle_cancelled_close(tcon, persistent_fid, volatile_fid);
> + if (rc)
> + cifs_put_tcon(tcon);
> +
> + return rc;
> +}
> +
> int
> smb2_handle_cancelled_mid(char *buffer, struct TCP_Server_Info *server)
> {
> struct smb2_sync_hdr *sync_hdr = (struct smb2_sync_hdr *)buffer;
> struct smb2_create_rsp *rsp = (struct smb2_create_rsp *)buffer;
> struct cifs_tcon *tcon;
> - struct close_cancelled_open *cancelled;
> + int rc;
>
> if (sync_hdr->Command != SMB2_CREATE ||
> sync_hdr->Status != STATUS_SUCCESS)
> return 0;
>
> - cancelled = kzalloc(sizeof(*cancelled), GFP_KERNEL);
> - if (!cancelled)
> - return -ENOMEM;
> -
> tcon = smb2_find_smb_tcon(server, sync_hdr->SessionId,
> sync_hdr->TreeId);
> - if (!tcon) {
> - kfree(cancelled);
> + if (!tcon)
> return -ENOENT;
> - }
>
> - cancelled->fid.persistent_fid = rsp->PersistentFileId;
> - cancelled->fid.volatile_fid = rsp->VolatileFileId;
> - cancelled->tcon = tcon;
> - INIT_WORK(&cancelled->work, smb2_cancelled_close_fid);
> - queue_work(cifsiod_wq, &cancelled->work);
> + rc = __smb2_handle_cancelled_close(tcon, rsp->PersistentFileId,
> + rsp->VolatileFileId);
> + if (rc)
> + cifs_put_tcon(tcon);
>
> - return 0;
> + return rc;
> }
>
> /**
> diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
> index 0aa40129dfb5..2f541e9efba1 100644
> --- a/fs/cifs/smb2pdu.c
> +++ b/fs/cifs/smb2pdu.c
> @@ -2942,7 +2942,21 @@ int
> SMB2_close(const unsigned int xid, struct cifs_tcon *tcon,
> u64 persistent_fid, u64 volatile_fid)
> {
> - return SMB2_close_flags(xid, tcon, persistent_fid, volatile_fid, 0);
> + int rc;
> + int tmp_rc;
> +
> + rc = SMB2_close_flags(xid, tcon, persistent_fid, volatile_fid, 0);
> +
> + /* retry close in a worker thread if this one is interrupted */
> + if (rc == -EINTR) {
> + tmp_rc = smb2_handle_cancelled_close(tcon, persistent_fid,
> + volatile_fid);
> + if (tmp_rc)
> + cifs_dbg(VFS, "handle cancelled close fid 0x%llx returned error %d\n",
> + persistent_fid, tmp_rc);
> + }
> +
> + return rc;
> }
>
> int
> diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h
> index 07ca72486cfa..e239f98093a9 100644
> --- a/fs/cifs/smb2proto.h
> +++ b/fs/cifs/smb2proto.h
> @@ -203,6 +203,9 @@ extern int SMB2_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
> extern int SMB2_oplock_break(const unsigned int xid, struct cifs_tcon *tcon,
> const u64 persistent_fid, const u64 volatile_fid,
> const __u8 oplock_level);
> +extern int smb2_handle_cancelled_close(struct cifs_tcon *tcon,
> + __u64 persistent_fid,
> + __u64 volatile_fid);
> extern int smb2_handle_cancelled_mid(char *buffer,
> struct TCP_Server_Info *server);
> void smb2_cancelled_close_fid(struct work_struct *work);
> --
> 2.17.1
>
--
Thanks,
Steve
prev parent reply other threads:[~2019-11-21 22:01 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-11-21 19:35 [PATCH 1/3] CIFS: Close open handle after interrupted close Pavel Shilovsky
2019-11-21 19:35 ` [PATCH 2/3] CIFS: Fix NULL pointer dereference in mid callback Pavel Shilovsky
2019-11-21 19:35 ` [PATCH 3/3] CIFS: Do not miss cancelled OPEN responses Pavel Shilovsky
2019-11-21 19:45 ` ronnie sahlberg
2019-11-21 22:00 ` Steve French [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=CAH2r5muszgyJWP6mUYs6nsHQQN-6ST63DJvyFus+STrJYP4-ug@mail.gmail.com \
--to=smfrench@gmail.com \
--cc=aaptel@suse.com \
--cc=linux-cifs@vger.kernel.org \
--cc=lsahlber@redhat.com \
--cc=paulo@paulo.ac \
--cc=piastryyy@gmail.com \
--cc=sorenson@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).