From patchwork Thu Mar 23 21:30:44 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve French X-Patchwork-Id: 1760573 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=2620:137:e000::1:20; helo=out1.vger.email; envelope-from=linux-cifs-owner@vger.kernel.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20210112 header.b=P6oIa9Tv; dkim-atps=neutral Received: from out1.vger.email (out1.vger.email [IPv6:2620:137:e000::1:20]) by legolas.ozlabs.org (Postfix) with ESMTP id 4PjJRs1dXkz1yXr for ; Fri, 24 Mar 2023 08:31:05 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229948AbjCWVbD (ORCPT ); Thu, 23 Mar 2023 17:31:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49248 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229877AbjCWVbC (ORCPT ); Thu, 23 Mar 2023 17:31:02 -0400 Received: from mail-lj1-x235.google.com (mail-lj1-x235.google.com [IPv6:2a00:1450:4864:20::235]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 367ACEB70 for ; Thu, 23 Mar 2023 14:30:58 -0700 (PDT) Received: by mail-lj1-x235.google.com with SMTP id e21so11385837ljn.7 for ; Thu, 23 Mar 2023 14:30:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1679607056; h=to:subject:message-id:date:from:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=oISTXFZRGS8O0K5O1KFmjjpiAApQuvt3L6TJvmx2xfc=; b=P6oIa9TvPyaiA7MJLG136gT28sHQ1Drpwi+VWLHlExzqjVcdoAhXl8SPfW1xZqDx3G EM225vMC1IwjlkxMgAaMB1kphxnTxIIfvWag99xV4kOjtGe9zFwfzfLud8EVW1hEjKKB hrlhQZOuCrhxtX4NaCwmoerlldxlwbCJABsKncb8LBR4OyK55PSg/G4pex20yxgbitzE w57kxsM3wSoX00ABCLt0nv7TfVOl4eWKy/guL81g2KUmTQGNIfv+Kw/Ut2qAywQ4p68s L/amcJxzr9IYobgVvTEdqEBZsT+8QZ7L3inCt8ZHGEiZo3Vth8BuhQ76Wn3x7WTIQlHu f46w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679607056; h=to:subject:message-id:date:from:mime-version:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=oISTXFZRGS8O0K5O1KFmjjpiAApQuvt3L6TJvmx2xfc=; b=FGsKhdKkzqYKJFlsQ9MsHWs+oFIFBrMfIC4+rqKy+/HjcAVj5Dz+q2gCTM2bu0Czn/ 7OQEEXyxYhqk8+Exey5MQE3N4O/aM8WxMfPBewQqMVPF7Ys34I3IpPCSlTP6l7LUgXQJ qnEJ4ogumSAf4GKIwqsFrMRFgWPNpyNhkSbTvlmFFVlbttsfeWA2CGnjILvA3kIDscnW EFf8CsF6VyeUIvF2MPucmZgE1lqqsKXca3bUtmt0E0Bie1OMev10/5CspHbO3X6+b74V RDHMnC1oYjhAabYFT7gCCX+7NLYeiKy239kJMTWuHsOBVqIMG3Yf8HH6GddOU8lxeCB9 l2Xw== X-Gm-Message-State: AAQBX9fQEhFAoPq8XuxMbFA9/EQdioeDuALUDlb4o8XwZu8Aqv01QXbY ui6A5z24RgXFubPFqmDFyvItAX+jKjwHwcqyT9ELKDM1Jj4= X-Google-Smtp-Source: AKy350YW6sA+Flj6kavTMIV18Am0Dwzhcxwh3XP7WUC6jYq6EqBVRjOczKm2jiNwuaBQT6ez0R+opvVTgUR7D0Ddz3Q= X-Received: by 2002:a2e:930f:0:b0:293:2f6e:91bf with SMTP id e15-20020a2e930f000000b002932f6e91bfmr201162ljh.7.1679607055938; Thu, 23 Mar 2023 14:30:55 -0700 (PDT) MIME-Version: 1.0 From: Steve French Date: Thu, 23 Mar 2023 16:30:44 -0500 Message-ID: Subject: [PATCH] smb3: fix unusable share after force unmount failure To: CIFS X-Spam-Status: No, score=-0.2 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org If user does forced unmount ("umount -f") while files are still open on the share (as was seen in a Kubernetes example running on SMB3.1.1 mount) then we were marking the share as "TID_EXITING" in umount_begin() which caused all subsequent operations (except write) to fail ... but unfortunately when umount_begin() is called we do not know yet that there are open files or active references on the share that would prevent unmount from succeeding. Kubernetes had example when they were doing umount -f when files were open which caused the share to become unusable until the files were closed (and the umount retried). Fix this so that TID_EXITING is not set until we are about to send the tree disconnect (not at the beginning of forced umounts in umount_begin) so that if "umount -f" fails (due to open files or references) the mount is still usable. Cc: stable@vger.kernel.org Signed-off-by: Steve French From ed55df0da747abdc1db75fef8baf3b0cac2c2de7 Mon Sep 17 00:00:00 2001 From: Steve French Date: Thu, 23 Mar 2023 16:20:02 -0500 Subject: [PATCH] smb3: fix unusable share after force unmount failure If user does forced unmount ("umount -f") while files are still open on the share (as was seen in a Kubernetes example running on SMB3.1.1 mount) then we were marking the share as "TID_EXITING" in umount_begin() which caused all subsequent operations (except write) to fail ... but unfortunately when umount_begin() is called we do not know yet that there are open files or active references on the share that would prevent unmount from succeeding. Kubernetes had example when they were doing umount -f when files were open which caused the share to become unusable until the files were closed (and the umount retried). Fix this so that TID_EXITING is not set until we are about to send the tree disconnect (not at the beginning of forced umounts in umount_begin) so that if "umount -f" fails (due to open files or references) the mount is still usable. Cc: stable@vger.kernel.org Signed-off-by: Steve French --- fs/cifs/cifsfs.c | 9 ++++++--- fs/cifs/cifssmb.c | 6 ++---- fs/cifs/connect.c | 4 +++- fs/cifs/smb2pdu.c | 8 ++------ 4 files changed, 13 insertions(+), 14 deletions(-) diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index cbcf210d56e4..ac9034fce409 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -731,13 +731,16 @@ static void cifs_umount_begin(struct super_block *sb) spin_lock(&tcon->tc_lock); if ((tcon->tc_count > 1) || (tcon->status == TID_EXITING)) { /* we have other mounts to same share or we have - already tried to force umount this and woken up + already tried to umount this and woken up all waiting network requests, nothing to do */ spin_unlock(&tcon->tc_lock); spin_unlock(&cifs_tcp_ses_lock); return; - } else if (tcon->tc_count == 1) - tcon->status = TID_EXITING; + } + /* + * can not set tcon->status to TID_EXITING yet since we don't know if umount -f will + * fail later (e.g. due to open files). TID_EXITING will be set just before tdis req sent + */ spin_unlock(&tcon->tc_lock); spin_unlock(&cifs_tcp_ses_lock); diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index a43c78396dd8..38a697eca305 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -86,13 +86,11 @@ cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command) /* * only tree disconnect, open, and write, (and ulogoff which does not - * have tcon) are allowed as we start force umount + * have tcon) are allowed as we start umount */ spin_lock(&tcon->tc_lock); if (tcon->status == TID_EXITING) { - if (smb_command != SMB_COM_WRITE_ANDX && - smb_command != SMB_COM_OPEN_ANDX && - smb_command != SMB_COM_TREE_DISCONNECT) { + if (smb_command != SMB_COM_TREE_DISCONNECT) { spin_unlock(&tcon->tc_lock); cifs_dbg(FYI, "can not send cmd %d while umounting\n", smb_command); diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index c3162ef9c9e9..4c3d4d4002b9 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -2341,8 +2341,10 @@ cifs_put_tcon(struct cifs_tcon *tcon) } xid = get_xid(); - if (ses->server->ops->tree_disconnect) + if (ses->server->ops->tree_disconnect) { + tcon->status = TID_EXITING; ses->server->ops->tree_disconnect(xid, tcon); + } _free_xid(xid); cifs_fscache_release_super_cookie(tcon); diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index a9fb95b7ef82..41b9f41a7505 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -165,13 +165,9 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon, spin_lock(&tcon->tc_lock); if (tcon->status == TID_EXITING) { /* - * only tree disconnect, open, and write, - * (and ulogoff which does not have tcon) - * are allowed as we start force umount. + * only tree disconnect allowed when disconnecting ... */ - if ((smb2_command != SMB2_WRITE) && - (smb2_command != SMB2_CREATE) && - (smb2_command != SMB2_TREE_DISCONNECT)) { + if (smb2_command != SMB2_TREE_DISCONNECT) { spin_unlock(&tcon->tc_lock); cifs_dbg(FYI, "can not send cmd %d while umounting\n", smb2_command); -- 2.34.1