Received: by 2002:a25:8b91:0:0:0:0:0 with SMTP id j17csp2284844ybl; Thu, 19 Dec 2019 11:01:02 -0800 (PST) X-Google-Smtp-Source: APXvYqx2E3mLhK7+oM+D+BnAcVMR/xx7/rF+7dzsa9fFjZyi/8XqWj/l61BnSpsMq9EtrGdROPJ2 X-Received: by 2002:a9d:7b4a:: with SMTP id f10mr10832782oto.4.1576782062781; Thu, 19 Dec 2019 11:01:02 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1576782062; cv=none; d=google.com; s=arc-20160816; b=M6YSKBxbLE0RH2wJe3J/eWDoRDR9UWsyTO9wDGAO25hKjwE/GrTimU0FPTQggWRGvr +kl6EPW7g670uTe/7o/knQaVBL/lozVne+lsmelZWNeyJR5mkwKerhGLOzetPb7xOTcA UgcAdgLN2M3NZSZHJqgHcA0U79hwVZuogtWW/1CRWvkcVB898k4a0fV2hsjhaC2IAFeP Hcox6vPgenWLjzRUQ57GE3uZxL9R2N1tF6iu1MRfWWcSnhJ3ufQN7GbLWxoY6G1OaE0I 5fpiZUBU5wLPX/gsZQdTJqtbP8XQ3rKyB+X2cFw9WqU9kO+V3El45/sLdC7GZ4fEW0oS CY7A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=BHO4iAwiwhg7MdxFJ68Yk638U/WXT6nd4oJn7o1NmXs=; b=bNx3SzslEQq96G1CkEfnuntxadETXDN7OKP584UuPX1pYYKjY+hXCC0tLPCMQUhdsc g5kpsz4n3RarYP9D69VVcfpJBns/RGrugBk4Lyw0DEopiSaVbrb9RWnW7tQHnwEGM77F ks/OemYVT8akaT4t2y2+bNl7uGHrTdoRpnEP0I3tr//aNsiLJvoVtE6FonlapaWXyxpP X/jot1w9zBRBKT+BLAPNOT0AaEVqxDxPmM+ADVkS4iKvXS1HDfl9udvQzKdkOd9Bt5ED V6iOr8UZBonXa4z09woN/avMB0P254IcXJYLkF5S0Jj+BlQC+wtsOIbh0iPiADGZcP4+ Pb+Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=L1bls7+f; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id c21si3827719otr.223.2019.12.19.11.00.49; Thu, 19 Dec 2019 11:01:02 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=L1bls7+f; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728662AbfLSS7d (ORCPT + 99 others); Thu, 19 Dec 2019 13:59:33 -0500 Received: from mail.kernel.org ([198.145.29.99]:48284 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730169AbfLSSxS (ORCPT ); Thu, 19 Dec 2019 13:53:18 -0500 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 859B0222C2; Thu, 19 Dec 2019 18:53:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1576781598; bh=1OLC7fK7e8K6+5vtj6+QZxcx8NewrfZH7SH2B2zBGCg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=L1bls7+fGzuRkZ4R0QnfyH3DV8g/pTWlglvkZT206JF/kG24yBDcHcDr34nMxI7dJ cfnUtIgqOK1oK0AzgO2agtHcH7PNijQ/AosD4DgYzVGC8gXjAy0bHy/rS2hbzGmtY6 pC66wVM4hmr/dGTF7uvZQgTl6a5BhfPk67FowDbI= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Frank Sorenson , Ronnie Sahlberg , Pavel Shilovsky , Steve French Subject: [PATCH 4.19 36/47] CIFS: Close open handle after interrupted close Date: Thu, 19 Dec 2019 19:34:50 +0100 Message-Id: <20191219182938.869369525@linuxfoundation.org> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20191219182857.659088743@linuxfoundation.org> References: <20191219182857.659088743@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Pavel Shilovsky commit 9150c3adbf24d77cfba37f03639d4a908ca4ac25 upstream. 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 Tested-by: Frank Sorenson Reviewed-by: Ronnie Sahlberg Signed-off-by: Pavel Shilovsky Signed-off-by: Steve French Signed-off-by: Greg Kroah-Hartman --- fs/cifs/smb2misc.c | 59 +++++++++++++++++++++++++++++++++++++++------------- fs/cifs/smb2pdu.c | 16 +++++++++++++- fs/cifs/smb2proto.h | 3 ++ 3 files changed, 63 insertions(+), 15 deletions(-) --- a/fs/cifs/smb2misc.c +++ b/fs/cifs/smb2misc.c @@ -743,36 +743,67 @@ smb2_cancelled_close_fid(struct work_str 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; } /** --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -2629,7 +2629,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 --- a/fs/cifs/smb2proto.h +++ b/fs/cifs/smb2proto.h @@ -204,6 +204,9 @@ extern int SMB2_set_compression(const un 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);