From patchwork Tue Mar 14 23:32:53 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paulo Alcantara X-Patchwork-Id: 13175122 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E85E1C6FD1F for ; Tue, 14 Mar 2023 23:33:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229675AbjCNXdJ (ORCPT ); Tue, 14 Mar 2023 19:33:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46190 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229512AbjCNXdI (ORCPT ); Tue, 14 Mar 2023 19:33:08 -0400 Received: from mx.manguebit.com (mx.manguebit.com [167.235.159.17]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 21F4338B44 for ; Tue, 14 Mar 2023 16:33:06 -0700 (PDT) From: Paulo Alcantara DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=manguebit.com; s=dkim; t=1678836784; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=nT7693H1iSjnvgTh2/cG6Uh6bWg78yeIxGCdd0Qr51c=; b=JqXtHF1XdJWXqIutS7BxIlPIdTBC6AGGMN1gRr0+wpgxsCylZ8jjJ+5JmuZj6otGxOx5/r 5jjswvfHkXBgHOdfaiwclsnw1KpSSosXnWSXBRGzCjJVOeH0ZAnhhRNvEIcQd3uvvPkY7L BLluPZlGfh/HX8qNUnqyMsvoWAIiU4GzG/kGhLily059pTJn82lVcD0HqpMkSu+7lsr7Ji pnFCUmWeMs+SoPwYsNPAScRWL3peQWhGrFNlYkjZ1094gFzeMZG30KkvXgLX9wc/0612hp OcM0QSrxNSWYdVb6O/uvNxm7FiLpVBLkEzrcaAByedtwdABQRplGimRP3IIK5A== ARC-Seal: i=1; s=dkim; d=manguebit.com; t=1678836784; a=rsa-sha256; cv=none; b=EXoJl2JOEUwEgENWGD8Wiybq8w8LaQk/lcllrnkZEGOWsjsuw1R8rNsu2Q4JoJ5ApsnbnA M8S6SL+8t3XGiAClZwx5ZhD8WnGGLf/N8BSo3JQqJ3B0zwUIxmVPUKX2K8rpEdC0mMdxUu /tNeWalDFm9vppDIapHvj6SQIZHjTDOZsErmpPMWldmKg3i9MwyAFu66eVRIgl36ADAjFz qqTHfL+OZCUHn0d5w158woEOyR98YYrg+ZXAQTr8NJjZdI6HyxOm2Zdq1uuvZ/brgfkahd EvZ6arN2dRSXHICZj0Oi05McS+GNpTT/7SRr8rOFQy30RoylYMUMGSXdoG6fJA== ARC-Authentication-Results: i=1; ORIGINATING; auth=pass smtp.auth=pc@manguebit.com smtp.mailfrom=pc@manguebit.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=manguebit.com; s=dkim; t=1678836784; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=nT7693H1iSjnvgTh2/cG6Uh6bWg78yeIxGCdd0Qr51c=; b=ZswbB0MbDNiQibe9Vqx9roD++pGzAVPRQlIlB31d/lYhrbIVJJZHKjMtKjHrIE+LU3rtfw aeAC35w+A5TpO3Kv9V962cG6y73sKV7LZqUbuNRiIPqYE3vK79A/59lJcX53zPMIeuFDH3 nmuv6Aj700Lir1/hP4bhEnbks21KXU0zM1B3erAJ3IUueWBLXG0ehIN/5dD+05CBj0P5At IfwcP9q7xdUN2q48IORwtoRZUfxmxQ2E+NcGxozdST7anCayFKBAvIWxMBtA8b607Y6DdG iokgcIklQfB/gM3AqSeZ+XcSCQ8EjpAouLYPKKXk1pZEn7v4B99m+TOydQAiRw== To: smfrench@gmail.com Cc: linux-cifs@vger.kernel.org, Paulo Alcantara Subject: [PATCH 1/4] cifs: set DFS root session in cifs_get_smb_ses() Date: Tue, 14 Mar 2023 20:32:53 -0300 Message-Id: <20230314233256.16468-1-pc.crab@mail.manguebit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Set the DFS root session pointer earlier when creating a new SMB session to prevent racing with smb2_reconnect(), cifs_reconnect_tcon() and DFS cache refresher. Signed-off-by: Paulo Alcantara (SUSE) --- fs/cifs/cifs_dfs_ref.c | 1 + fs/cifs/cifsglob.h | 1 - fs/cifs/connect.c | 1 + fs/cifs/dfs.c | 19 ++++++++----------- fs/cifs/dfs.h | 3 ++- fs/cifs/fs_context.h | 1 + 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/fs/cifs/cifs_dfs_ref.c b/fs/cifs/cifs_dfs_ref.c index 2b1a8d55b4ec..cb40074feb3e 100644 --- a/fs/cifs/cifs_dfs_ref.c +++ b/fs/cifs/cifs_dfs_ref.c @@ -179,6 +179,7 @@ static struct vfsmount *cifs_dfs_do_automount(struct path *path) tmp.source = full_path; tmp.leaf_fullpath = NULL; tmp.UNC = tmp.prepath = NULL; + tmp.dfs_root_ses = NULL; rc = smb3_fs_context_dup(ctx, &tmp); if (rc) { diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 8a37b1553dc6..a6f3e03e5790 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -1749,7 +1749,6 @@ struct cifs_mount_ctx { struct TCP_Server_Info *server; struct cifs_ses *ses; struct cifs_tcon *tcon; - struct cifs_ses *root_ses; uuid_t mount_id; char *origin_fullpath, *leaf_fullpath; }; diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 3d07729c91a1..5038dcd045b9 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -2229,6 +2229,7 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx) * need to lock before changing something in the session. */ spin_lock(&cifs_tcp_ses_lock); + ses->dfs_root_ses = ctx->dfs_root_ses; list_add(&ses->smb_ses_list, &server->smb_ses_list); spin_unlock(&cifs_tcp_ses_lock); diff --git a/fs/cifs/dfs.c b/fs/cifs/dfs.c index d37af02902c5..eb35259b48fa 100644 --- a/fs/cifs/dfs.c +++ b/fs/cifs/dfs.c @@ -95,25 +95,22 @@ static int get_session(struct cifs_mount_ctx *mnt_ctx, const char *full_path) ctx->leaf_fullpath = (char *)full_path; rc = cifs_mount_get_session(mnt_ctx); ctx->leaf_fullpath = NULL; - if (!rc) { - struct cifs_ses *ses = mnt_ctx->ses; - mutex_lock(&ses->session_mutex); - ses->dfs_root_ses = mnt_ctx->root_ses; - mutex_unlock(&ses->session_mutex); - } return rc; } static void set_root_ses(struct cifs_mount_ctx *mnt_ctx) { - if (mnt_ctx->ses) { + struct smb3_fs_context *ctx = mnt_ctx->fs_ctx; + struct cifs_ses *ses = mnt_ctx->ses; + + if (ses) { spin_lock(&cifs_tcp_ses_lock); - mnt_ctx->ses->ses_count++; + ses->ses_count++; spin_unlock(&cifs_tcp_ses_lock); - dfs_cache_add_refsrv_session(&mnt_ctx->mount_id, mnt_ctx->ses); + dfs_cache_add_refsrv_session(&mnt_ctx->mount_id, ses); } - mnt_ctx->root_ses = mnt_ctx->ses; + ctx->dfs_root_ses = mnt_ctx->ses; } static int get_dfs_conn(struct cifs_mount_ctx *mnt_ctx, const char *ref_path, const char *full_path, @@ -260,7 +257,7 @@ int dfs_mount_share(struct cifs_mount_ctx *mnt_ctx, bool *isdfs) rc = get_session(mnt_ctx, NULL); if (rc) return rc; - mnt_ctx->root_ses = mnt_ctx->ses; + ctx->dfs_root_ses = mnt_ctx->ses; /* * If called with 'nodfs' mount option, then skip DFS resolving. Otherwise unconditionally * try to get an DFS referral (even cached) to determine whether it is an DFS mount. diff --git a/fs/cifs/dfs.h b/fs/cifs/dfs.h index 344bea6d8bab..baf16df55d7e 100644 --- a/fs/cifs/dfs.h +++ b/fs/cifs/dfs.h @@ -22,9 +22,10 @@ static inline char *dfs_get_path(struct cifs_sb_info *cifs_sb, const char *path) static inline int dfs_get_referral(struct cifs_mount_ctx *mnt_ctx, const char *path, struct dfs_info3_param *ref, struct dfs_cache_tgt_list *tl) { + struct smb3_fs_context *ctx = mnt_ctx->fs_ctx; struct cifs_sb_info *cifs_sb = mnt_ctx->cifs_sb; - return dfs_cache_find(mnt_ctx->xid, mnt_ctx->root_ses, cifs_sb->local_nls, + return dfs_cache_find(mnt_ctx->xid, ctx->dfs_root_ses, cifs_sb->local_nls, cifs_remap(cifs_sb), path, ref, tl); } diff --git a/fs/cifs/fs_context.h b/fs/cifs/fs_context.h index 44cb5639ed3b..1b8d4e27f831 100644 --- a/fs/cifs/fs_context.h +++ b/fs/cifs/fs_context.h @@ -265,6 +265,7 @@ struct smb3_fs_context { bool rootfs:1; /* if it's a SMB root file system */ bool witness:1; /* use witness protocol */ char *leaf_fullpath; + struct cifs_ses *dfs_root_ses; }; extern const struct fs_parameter_spec smb3_fs_parameters[]; From patchwork Tue Mar 14 23:32:54 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paulo Alcantara X-Patchwork-Id: 13175124 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id F0A8AC6FD1F for ; Tue, 14 Mar 2023 23:33:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229765AbjCNXdM (ORCPT ); Tue, 14 Mar 2023 19:33:12 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46304 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229512AbjCNXdK (ORCPT ); Tue, 14 Mar 2023 19:33:10 -0400 Received: from mx.manguebit.com (mx.manguebit.com [167.235.159.17]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 57A6523A5B for ; Tue, 14 Mar 2023 16:33:08 -0700 (PDT) From: Paulo Alcantara DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=manguebit.com; s=dkim; t=1678836786; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=AZ6RfcWY1tW2/no2bHJ+d2/n7VQ2xxPczS8o8hWeYDo=; b=RjKPrDPmV4dPotAj6Mer2QjvHXYfLV5Q61iwBraVORf0Rf90AGFeePICDlF6arSoQOepyx MkmXuiXcpxD26MdV7eA8yokkLzNkiZCYfSSfDxez+a6FVQLcRPHVbt+vSl0v/fVR84kn1C sYJxlESkdeVwsU7HB8pgO81JhnnXfKng4yePCFnKOyUf3QAc76tycGWQkKKjYYdVQDhCoW 5wzmRiuTVHfd9trPMxuQyxeJ5cyPRqoIGSGZBz7WJtn5UCQqfZHPQHnYhs2oWV6U/X/bPe XIuJmlgXdBm5Ot5hEw28z5wqJLhTBnL2h/CoyaNcjLvvujfIsdx9G6Y53+JYFA== ARC-Seal: i=1; s=dkim; d=manguebit.com; t=1678836786; a=rsa-sha256; cv=none; b=A7eERzfySBIQd50xMFtsde+9MTCO6ub7U62jyQ5XNcT5nr/vhcoOk7aS8Bqixl3FYg1dIX Z/2HSUTNd+77eYES14hm1AUbGvHJZIcG+GQRX5CHPdHoVDlyK5yDk5zEWW1kou/l9UWwWp Kve2MTI7DY7rEjSzbqYBp3bbYjs9XV05ptHkOSjjLPZcYGl3q/olavC1IbjmrxPFzZn5CG 3vn1XXRg08o97VhunNcQ9lrx9ZmbMLHKOPFIK3TEvXGXsK4fg9geP9d30RaFw40XW5/EFF 3TnOvrs00/ihMcaElYDb/+m3zxW26jHL4/L7Eh/IBRgMPJEGxMUh/OseVUK0pA== ARC-Authentication-Results: i=1; ORIGINATING; auth=pass smtp.auth=pc@manguebit.com smtp.mailfrom=pc@manguebit.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=manguebit.com; s=dkim; t=1678836786; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=AZ6RfcWY1tW2/no2bHJ+d2/n7VQ2xxPczS8o8hWeYDo=; b=iMeT/HgRqwqyvmEKcA9PPnwHafH88kD62nvLxoUzXrYe+mDZxrmwb+bclwtg7cy/rfwtqV 7nFkuJAjUFPT20zKVJVgCUUOoxxBSJf3fysKYY1HDDbkdbOGn2uz2czdrkrDulYXczC2Re KzQ5MLLCRJZjRxbozddTgVwz57hFbAVylzOMFmppltbW9mlfxiIfa8onOjfVQFADhL27h9 rduLWS4drX/nSki231/wrqGK9Uyt1NIfcDeZBXBrAeguC8w19+QIqaV/xt3gQkhBl93IZc I/RzthEZubXSjkmqTiqjfkgj0j06jBlkHbAZBe//OGX8TkEmfn/lVmRHEDS27A== To: smfrench@gmail.com Cc: linux-cifs@vger.kernel.org, Paulo Alcantara Subject: [PATCH 2/4] cifs: fix use-after-free bug in refresh_cache_worker() Date: Tue, 14 Mar 2023 20:32:54 -0300 Message-Id: <20230314233256.16468-2-pc.crab@mail.manguebit.com> In-Reply-To: <20230314233256.16468-1-pc@manguebit.com> References: <20230314233256.16468-1-pc@manguebit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org The UAF bug occurred because we were putting DFS root sessions in cifs_umount() while DFS cache refresher was being executed. Make DFS root sessions have same lifetime as DFS tcons so we can avoid the use-after-free bug is DFS cache refresher and other places that require IPCs to get new DFS referrals on. Also, get rid of mount group handling in DFS cache as we no longer need it. This fixes below use-after-free bug catched by KASAN [ 379.946955] BUG: KASAN: use-after-free in __refresh_tcon.isra.0+0x10b/0xc10 [cifs] [ 379.947642] Read of size 8 at addr ffff888018f57030 by task kworker/u4:3/56 [ 379.948096] [ 379.948208] CPU: 0 PID: 56 Comm: kworker/u4:3 Not tainted 6.2.0-rc7-lku #23 [ 379.948661] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.16.0-0-gd239552-rebuilt.opensuse.org 04/01/2014 [ 379.949368] Workqueue: cifs-dfscache refresh_cache_worker [cifs] [ 379.949942] Call Trace: [ 379.950113] [ 379.950260] dump_stack_lvl+0x50/0x67 [ 379.950510] print_report+0x16a/0x48e [ 379.950759] ? __virt_addr_valid+0xd8/0x160 [ 379.951040] ? __phys_addr+0x41/0x80 [ 379.951285] kasan_report+0xdb/0x110 [ 379.951533] ? __refresh_tcon.isra.0+0x10b/0xc10 [cifs] [ 379.952056] ? __refresh_tcon.isra.0+0x10b/0xc10 [cifs] [ 379.952585] __refresh_tcon.isra.0+0x10b/0xc10 [cifs] [ 379.953096] ? __pfx___refresh_tcon.isra.0+0x10/0x10 [cifs] [ 379.953637] ? __pfx___mutex_lock+0x10/0x10 [ 379.953915] ? lock_release+0xb6/0x720 [ 379.954167] ? __pfx_lock_acquire+0x10/0x10 [ 379.954443] ? refresh_cache_worker+0x34e/0x6d0 [cifs] [ 379.954960] ? __pfx_wb_workfn+0x10/0x10 [ 379.955239] refresh_cache_worker+0x4ad/0x6d0 [cifs] [ 379.955755] ? __pfx_refresh_cache_worker+0x10/0x10 [cifs] [ 379.956323] ? __pfx_lock_acquired+0x10/0x10 [ 379.956615] ? read_word_at_a_time+0xe/0x20 [ 379.956898] ? lockdep_hardirqs_on_prepare+0x12/0x220 [ 379.957235] process_one_work+0x535/0x990 [ 379.957509] ? __pfx_process_one_work+0x10/0x10 [ 379.957812] ? lock_acquired+0xb7/0x5f0 [ 379.958069] ? __list_add_valid+0x37/0xd0 [ 379.958341] ? __list_add_valid+0x37/0xd0 [ 379.958611] worker_thread+0x8e/0x630 [ 379.958861] ? __pfx_worker_thread+0x10/0x10 [ 379.959148] kthread+0x17d/0x1b0 [ 379.959369] ? __pfx_kthread+0x10/0x10 [ 379.959630] ret_from_fork+0x2c/0x50 [ 379.959879] Signed-off-by: Paulo Alcantara (SUSE) --- fs/cifs/cifs_fs_sb.h | 2 - fs/cifs/cifsglob.h | 3 +- fs/cifs/connect.c | 9 +-- fs/cifs/dfs.c | 52 ++++++++++++---- fs/cifs/dfs.h | 16 +++++ fs/cifs/dfs_cache.c | 140 ------------------------------------------- fs/cifs/dfs_cache.h | 2 - fs/cifs/misc.c | 7 +++ 8 files changed, 67 insertions(+), 164 deletions(-) diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h index 013a4bd65280..651759192280 100644 --- a/fs/cifs/cifs_fs_sb.h +++ b/fs/cifs/cifs_fs_sb.h @@ -61,8 +61,6 @@ struct cifs_sb_info { /* only used when CIFS_MOUNT_USE_PREFIX_PATH is set */ char *prepath; - /* randomly generated 128-bit number for indexing dfs mount groups in referral cache */ - uuid_t dfs_mount_id; /* * Indicate whether serverino option was turned off later * (cifs_autodisable_serverino) in order to match new mounts. diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index a6f3e03e5790..9da301d18491 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -1233,6 +1233,7 @@ struct cifs_tcon { /* BB add field for back pointer to sb struct(s)? */ #ifdef CONFIG_CIFS_DFS_UPCALL struct list_head ulist; /* cache update list */ + struct list_head dfs_ses_list; #endif struct delayed_work query_interfaces; /* query interfaces workqueue job */ }; @@ -1749,8 +1750,8 @@ struct cifs_mount_ctx { struct TCP_Server_Info *server; struct cifs_ses *ses; struct cifs_tcon *tcon; - uuid_t mount_id; char *origin_fullpath, *leaf_fullpath; + struct list_head dfs_ses_list; }; static inline void free_dfs_info_param(struct dfs_info3_param *param) diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 5038dcd045b9..a356c8c2fae0 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -3408,7 +3408,8 @@ int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx) bool isdfs; int rc; - uuid_gen(&mnt_ctx.mount_id); + INIT_LIST_HEAD(&mnt_ctx.dfs_ses_list); + rc = dfs_mount_share(&mnt_ctx, &isdfs); if (rc) goto error; @@ -3428,7 +3429,6 @@ int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx) kfree(cifs_sb->prepath); cifs_sb->prepath = ctx->prepath; ctx->prepath = NULL; - uuid_copy(&cifs_sb->dfs_mount_id, &mnt_ctx.mount_id); out: cifs_try_adding_channels(cifs_sb, mnt_ctx.ses); @@ -3440,7 +3440,7 @@ int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx) return rc; error: - dfs_cache_put_refsrv_sessions(&mnt_ctx.mount_id); + dfs_put_root_smb_sessions(&mnt_ctx.dfs_ses_list); kfree(mnt_ctx.origin_fullpath); kfree(mnt_ctx.leaf_fullpath); cifs_mount_put_conns(&mnt_ctx); @@ -3638,9 +3638,6 @@ cifs_umount(struct cifs_sb_info *cifs_sb) spin_unlock(&cifs_sb->tlink_tree_lock); kfree(cifs_sb->prepath); -#ifdef CONFIG_CIFS_DFS_UPCALL - dfs_cache_put_refsrv_sessions(&cifs_sb->dfs_mount_id); -#endif call_rcu(&cifs_sb->rcu, delayed_free); } diff --git a/fs/cifs/dfs.c b/fs/cifs/dfs.c index eb35259b48fa..fc86de9ebea7 100644 --- a/fs/cifs/dfs.c +++ b/fs/cifs/dfs.c @@ -99,18 +99,27 @@ static int get_session(struct cifs_mount_ctx *mnt_ctx, const char *full_path) return rc; } -static void set_root_ses(struct cifs_mount_ctx *mnt_ctx) +static int get_root_smb_session(struct cifs_mount_ctx *mnt_ctx) { struct smb3_fs_context *ctx = mnt_ctx->fs_ctx; + struct dfs_root_ses *root_ses; struct cifs_ses *ses = mnt_ctx->ses; if (ses) { + root_ses = kmalloc(sizeof(*root_ses), GFP_KERNEL); + if (!root_ses) + return -ENOMEM; + + INIT_LIST_HEAD(&root_ses->list); + spin_lock(&cifs_tcp_ses_lock); ses->ses_count++; spin_unlock(&cifs_tcp_ses_lock); - dfs_cache_add_refsrv_session(&mnt_ctx->mount_id, ses); + root_ses->ses = ses; + list_add_tail(&root_ses->list, &mnt_ctx->dfs_ses_list); } - ctx->dfs_root_ses = mnt_ctx->ses; + ctx->dfs_root_ses = ses; + return 0; } static int get_dfs_conn(struct cifs_mount_ctx *mnt_ctx, const char *ref_path, const char *full_path, @@ -118,7 +127,8 @@ static int get_dfs_conn(struct cifs_mount_ctx *mnt_ctx, const char *ref_path, co { struct smb3_fs_context *ctx = mnt_ctx->fs_ctx; struct dfs_info3_param ref = {}; - int rc; + bool is_refsrv = false; + int rc, rc2; rc = dfs_cache_get_tgt_referral(ref_path + 1, tit, &ref); if (rc) @@ -133,8 +143,7 @@ static int get_dfs_conn(struct cifs_mount_ctx *mnt_ctx, const char *ref_path, co if (rc) goto out; - if (ref.flags & DFSREF_REFERRAL_SERVER) - set_root_ses(mnt_ctx); + is_refsrv = !!(ref.flags & DFSREF_REFERRAL_SERVER); rc = -EREMOTE; if (ref.flags & DFSREF_STORAGE_SERVER) { @@ -143,13 +152,17 @@ static int get_dfs_conn(struct cifs_mount_ctx *mnt_ctx, const char *ref_path, co goto out; /* some servers may not advertise referral capability under ref.flags */ - if (!(ref.flags & DFSREF_REFERRAL_SERVER) && - is_tcon_dfs(mnt_ctx->tcon)) - set_root_ses(mnt_ctx); + is_refsrv |= is_tcon_dfs(mnt_ctx->tcon); rc = cifs_is_path_remote(mnt_ctx); } + if (rc == -EREMOTE && is_refsrv) { + rc2 = get_root_smb_session(mnt_ctx); + if (rc2) + rc = rc2; + } + out: free_dfs_info_param(&ref); return rc; @@ -162,6 +175,7 @@ static int __dfs_mount_share(struct cifs_mount_ctx *mnt_ctx) char *ref_path = NULL, *full_path = NULL; struct dfs_cache_tgt_iterator *tit; struct TCP_Server_Info *server; + struct cifs_tcon *tcon; char *origin_fullpath = NULL; int num_links = 0; int rc; @@ -231,12 +245,22 @@ static int __dfs_mount_share(struct cifs_mount_ctx *mnt_ctx) if (!rc) { server = mnt_ctx->server; + tcon = mnt_ctx->tcon; mutex_lock(&server->refpath_lock); - server->origin_fullpath = origin_fullpath; - server->current_fullpath = server->leaf_fullpath; + if (!server->origin_fullpath) { + server->origin_fullpath = origin_fullpath; + server->current_fullpath = server->leaf_fullpath; + origin_fullpath = NULL; + } mutex_unlock(&server->refpath_lock); - origin_fullpath = NULL; + + if (list_empty(&tcon->dfs_ses_list)) { + list_replace_init(&mnt_ctx->dfs_ses_list, + &tcon->dfs_ses_list); + } else { + dfs_put_root_smb_sessions(&mnt_ctx->dfs_ses_list); + } } out: @@ -277,7 +301,9 @@ int dfs_mount_share(struct cifs_mount_ctx *mnt_ctx, bool *isdfs) } *isdfs = true; - set_root_ses(mnt_ctx); + rc = get_root_smb_session(mnt_ctx); + if (rc) + return rc; return __dfs_mount_share(mnt_ctx); } diff --git a/fs/cifs/dfs.h b/fs/cifs/dfs.h index baf16df55d7e..13f26e01f7b9 100644 --- a/fs/cifs/dfs.h +++ b/fs/cifs/dfs.h @@ -10,6 +10,11 @@ #include "fs_context.h" #include "cifs_unicode.h" +struct dfs_root_ses { + struct list_head list; + struct cifs_ses *ses; +}; + int dfs_parse_target_referral(const char *full_path, const struct dfs_info3_param *ref, struct smb3_fs_context *ctx); int dfs_mount_share(struct cifs_mount_ctx *mnt_ctx, bool *isdfs); @@ -44,4 +49,15 @@ static inline char *dfs_get_automount_devname(struct dentry *dentry, void *page) true); } +static inline void dfs_put_root_smb_sessions(struct list_head *head) +{ + struct dfs_root_ses *root, *tmp; + + list_for_each_entry_safe(root, tmp, head, list) { + list_del_init(&root->list); + cifs_put_smb_ses(root->ses); + kfree(root); + } +} + #endif /* _CIFS_DFS_H */ diff --git a/fs/cifs/dfs_cache.c b/fs/cifs/dfs_cache.c index ac86bd0ebd63..1c59811bfa73 100644 --- a/fs/cifs/dfs_cache.c +++ b/fs/cifs/dfs_cache.c @@ -49,17 +49,6 @@ struct cache_entry { struct cache_dfs_tgt *tgthint; }; -/* List of referral server sessions per dfs mount */ -struct mount_group { - struct list_head list; - uuid_t id; - struct cifs_ses *sessions[CACHE_MAX_ENTRIES]; - int num_sessions; - spinlock_t lock; - struct list_head refresh_list; - struct kref refcount; -}; - static struct kmem_cache *cache_slab __read_mostly; static struct workqueue_struct *dfscache_wq __read_mostly; @@ -76,85 +65,10 @@ static atomic_t cache_count; static struct hlist_head cache_htable[CACHE_HTABLE_SIZE]; static DECLARE_RWSEM(htable_rw_lock); -static LIST_HEAD(mount_group_list); -static DEFINE_MUTEX(mount_group_list_lock); - static void refresh_cache_worker(struct work_struct *work); static DECLARE_DELAYED_WORK(refresh_task, refresh_cache_worker); -static void __mount_group_release(struct mount_group *mg) -{ - int i; - - for (i = 0; i < mg->num_sessions; i++) - cifs_put_smb_ses(mg->sessions[i]); - kfree(mg); -} - -static void mount_group_release(struct kref *kref) -{ - struct mount_group *mg = container_of(kref, struct mount_group, refcount); - - mutex_lock(&mount_group_list_lock); - list_del(&mg->list); - mutex_unlock(&mount_group_list_lock); - __mount_group_release(mg); -} - -static struct mount_group *find_mount_group_locked(const uuid_t *id) -{ - struct mount_group *mg; - - list_for_each_entry(mg, &mount_group_list, list) { - if (uuid_equal(&mg->id, id)) - return mg; - } - return ERR_PTR(-ENOENT); -} - -static struct mount_group *__get_mount_group_locked(const uuid_t *id) -{ - struct mount_group *mg; - - mg = find_mount_group_locked(id); - if (!IS_ERR(mg)) - return mg; - - mg = kmalloc(sizeof(*mg), GFP_KERNEL); - if (!mg) - return ERR_PTR(-ENOMEM); - kref_init(&mg->refcount); - uuid_copy(&mg->id, id); - mg->num_sessions = 0; - spin_lock_init(&mg->lock); - list_add(&mg->list, &mount_group_list); - return mg; -} - -static struct mount_group *get_mount_group(const uuid_t *id) -{ - struct mount_group *mg; - - mutex_lock(&mount_group_list_lock); - mg = __get_mount_group_locked(id); - if (!IS_ERR(mg)) - kref_get(&mg->refcount); - mutex_unlock(&mount_group_list_lock); - - return mg; -} - -static void free_mount_group_list(void) -{ - struct mount_group *mg, *tmp_mg; - - list_for_each_entry_safe(mg, tmp_mg, &mount_group_list, list) { - list_del_init(&mg->list); - __mount_group_release(mg); - } -} - /** * dfs_cache_canonical_path - get a canonical DFS path * @@ -704,7 +618,6 @@ void dfs_cache_destroy(void) { cancel_delayed_work_sync(&refresh_task); unload_nls(cache_cp); - free_mount_group_list(); flush_cache_ents(); kmem_cache_destroy(cache_slab); destroy_workqueue(dfscache_wq); @@ -1111,54 +1024,6 @@ int dfs_cache_get_tgt_referral(const char *path, const struct dfs_cache_tgt_iter return rc; } -/** - * dfs_cache_add_refsrv_session - add SMB session of referral server - * - * @mount_id: mount group uuid to lookup. - * @ses: reference counted SMB session of referral server. - */ -void dfs_cache_add_refsrv_session(const uuid_t *mount_id, struct cifs_ses *ses) -{ - struct mount_group *mg; - - if (WARN_ON_ONCE(!mount_id || uuid_is_null(mount_id) || !ses)) - return; - - mg = get_mount_group(mount_id); - if (WARN_ON_ONCE(IS_ERR(mg))) - return; - - spin_lock(&mg->lock); - if (mg->num_sessions < ARRAY_SIZE(mg->sessions)) - mg->sessions[mg->num_sessions++] = ses; - spin_unlock(&mg->lock); - kref_put(&mg->refcount, mount_group_release); -} - -/** - * dfs_cache_put_refsrv_sessions - put all referral server sessions - * - * Put all SMB sessions from the given mount group id. - * - * @mount_id: mount group uuid to lookup. - */ -void dfs_cache_put_refsrv_sessions(const uuid_t *mount_id) -{ - struct mount_group *mg; - - if (!mount_id || uuid_is_null(mount_id)) - return; - - mutex_lock(&mount_group_list_lock); - mg = find_mount_group_locked(mount_id); - if (IS_ERR(mg)) { - mutex_unlock(&mount_group_list_lock); - return; - } - mutex_unlock(&mount_group_list_lock); - kref_put(&mg->refcount, mount_group_release); -} - /* Extract share from DFS target and return a pointer to prefix path or NULL */ static const char *parse_target_share(const char *target, char **share) { @@ -1384,11 +1249,6 @@ int dfs_cache_remount_fs(struct cifs_sb_info *cifs_sb) cifs_dbg(FYI, "%s: not a dfs mount\n", __func__); return 0; } - - if (uuid_is_null(&cifs_sb->dfs_mount_id)) { - cifs_dbg(FYI, "%s: no dfs mount group id\n", __func__); - return -EINVAL; - } /* * After reconnecting to a different server, unique ids won't match anymore, so we disable * serverino. This prevents dentry revalidation to think the dentry are stale (ESTALE). diff --git a/fs/cifs/dfs_cache.h b/fs/cifs/dfs_cache.h index be3b5a44cf82..e0d39393035a 100644 --- a/fs/cifs/dfs_cache.h +++ b/fs/cifs/dfs_cache.h @@ -40,8 +40,6 @@ int dfs_cache_get_tgt_referral(const char *path, const struct dfs_cache_tgt_iter struct dfs_info3_param *ref); int dfs_cache_get_tgt_share(char *path, const struct dfs_cache_tgt_iterator *it, char **share, char **prefix); -void dfs_cache_put_refsrv_sessions(const uuid_t *mount_id); -void dfs_cache_add_refsrv_session(const uuid_t *mount_id, struct cifs_ses *ses); char *dfs_cache_canonical_path(const char *path, const struct nls_table *cp, int remap); int dfs_cache_remount_fs(struct cifs_sb_info *cifs_sb); diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index a0d286ee723d..6f9c78650528 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c @@ -22,6 +22,7 @@ #ifdef CONFIG_CIFS_DFS_UPCALL #include "dns_resolve.h" #include "dfs_cache.h" +#include "dfs.h" #endif #include "fs_context.h" #include "cached_dir.h" @@ -134,6 +135,9 @@ tconInfoAlloc(void) spin_lock_init(&ret_buf->stat_lock); atomic_set(&ret_buf->num_local_opens, 0); atomic_set(&ret_buf->num_remote_opens, 0); +#ifdef CONFIG_CIFS_DFS_UPCALL + INIT_LIST_HEAD(&ret_buf->dfs_ses_list); +#endif return ret_buf; } @@ -149,6 +153,9 @@ tconInfoFree(struct cifs_tcon *tcon) atomic_dec(&tconInfoAllocCount); kfree(tcon->nativeFileSystem); kfree_sensitive(tcon->password); +#ifdef CONFIG_CIFS_DFS_UPCALL + dfs_put_root_smb_sessions(&tcon->dfs_ses_list); +#endif kfree(tcon); } From patchwork Tue Mar 14 23:32:55 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paulo Alcantara X-Patchwork-Id: 13175123 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 61B54C7618B for ; Tue, 14 Mar 2023 23:33:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229512AbjCNXdM (ORCPT ); Tue, 14 Mar 2023 19:33:12 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46366 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229707AbjCNXdL (ORCPT ); Tue, 14 Mar 2023 19:33:11 -0400 Received: from mx.manguebit.com (mx.manguebit.com [IPv6:2a01:4f8:1c1e:a2ae::2]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 97B0738B44 for ; Tue, 14 Mar 2023 16:33:10 -0700 (PDT) From: Paulo Alcantara DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=manguebit.com; s=dkim; t=1678836789; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=WUHMbk4HVQ3cMaPv9cOozVq4JrvXW3GMGQ1hQuvKjPg=; b=mNGaTWNm+tgqXrz7CbmOXr9eGbzu8KsmKO60a0R5LZVGIgaH3klLcVeKuEKK6HZt+d+L8I Jr0q9oytLfassBDu3YihFdXem6QgQ3b+SvVt1X+0HoZZXBEL0tanPCf/Ps2CpPEfo6yYZp rd2QyN7wfNQoKpeFQaCQstS4unbni50KBy6faPshdvJC/S8VImhcYm26CTvd4z56bwohom bGvxwRHMOyHeVJLC4tNyNIv0jxLVFPCcbvmkwwiZadhT7qhxGPSFTFsj/Gahb8FH6FhHBe Xui9r6eClPGna0R+s3dWj7arCClBSlRrtH22tjzIDVsL9BDBLn2Ph9I7V2hXpg== ARC-Seal: i=1; s=dkim; d=manguebit.com; t=1678836789; a=rsa-sha256; cv=none; b=ReygoQNWHZVWU8ygGAHMZqDPyW1trHxqsM8nTc6oRhpPJjzeI7OhFThEUN2hXgymRfT4jr mJ89A4/yfuslKrW6NNYPC0zlA9fXlptqrqXXf4kYKgvjD2tMK4AJhqmTPYn3noZczVEkKU dS7Z/ielZIfFUBCml9GIvAG73V+yRojot0WZGXvfL7vHF93MZRwqIge1dWlaYyBo6okroj UcSngY0o9O/pKc0KiqIA/23KtWazQm7BGJZOfM48lcR6AJzQ2LrCgEccR40iSVXgNPvuq0 lpupE5Z2nNZvXQaVXb/lTAaVcuLozYn+w6oXc1xGbBz0GPiziQ6ziVeP9jioog== ARC-Authentication-Results: i=1; ORIGINATING; auth=pass smtp.auth=pc@manguebit.com smtp.mailfrom=pc@manguebit.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=manguebit.com; s=dkim; t=1678836789; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=WUHMbk4HVQ3cMaPv9cOozVq4JrvXW3GMGQ1hQuvKjPg=; b=sc1jw5UlYG88p3cKd0CbNBiQ7X2l322rgSpGBFHFpBkY0tUdbqyX3VdAyUEFw/GdSrsgC9 2nqlcJtPs0eXqAmX5ocoS5+4PeBnPTRYUfDdVwaYgLWjlOTxf05/4dBoCuecBx/e3PvWuS 9BdNTNQNI07f7Nbxty5mC+BenII1GjAlBQqxTqr0xeExFdWar4v5OiMIaWsEiiyD/dCkut oZ2lEkdmJYMq3Mbe2Ma4bw1COCEUgOBpNg+YgNYb3bVd0sDYz+Pv2V+mEDS1t2zPp8qkc/ uXeFaLcaesLZOBJ7fko2mTiPUxtr7wau7fB9293HvZV9Ai3aSBxluRKq7YPu6g== To: smfrench@gmail.com Cc: linux-cifs@vger.kernel.org, Paulo Alcantara Subject: [PATCH 3/4] cifs: return DFS root session id in DebugData Date: Tue, 14 Mar 2023 20:32:55 -0300 Message-Id: <20230314233256.16468-3-pc.crab@mail.manguebit.com> In-Reply-To: <20230314233256.16468-1-pc@manguebit.com> References: <20230314233256.16468-1-pc@manguebit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Return the DFS root session id in /proc/fs/cifs/DebugData to make it easier to track which IPC tcon was used to get new DFS referrals for a specific connection. A simple output of it would be Sessions: 1) Address: 192.168.1.13 Uses: 1 Capability: 0x300067 Session Status: 1 Security type: RawNTLMSSP SessionId: 0xd80000000009 User: 0 Cred User: 0 DFS root session id: 0x128006c000035 Signed-off-by: Paulo Alcantara (SUSE) --- fs/cifs/cifs_debug.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c index 1911f7016fa1..19a70a69c760 100644 --- a/fs/cifs/cifs_debug.c +++ b/fs/cifs/cifs_debug.c @@ -420,6 +420,11 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v) from_kuid(&init_user_ns, ses->linux_uid), from_kuid(&init_user_ns, ses->cred_uid)); + if (ses->dfs_root_ses) { + seq_printf(m, "\n\tDFS root session id: 0x%llx", + ses->dfs_root_ses->Suid); + } + spin_lock(&ses->chan_lock); if (CIFS_CHAN_NEEDS_RECONNECT(ses, 0)) seq_puts(m, "\tPrimary channel: DISCONNECTED "); From patchwork Tue Mar 14 23:32:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paulo Alcantara X-Patchwork-Id: 13175125 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BBF0CC6FD1D for ; Tue, 14 Mar 2023 23:33:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229707AbjCNXdQ (ORCPT ); Tue, 14 Mar 2023 19:33:16 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46492 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229784AbjCNXdO (ORCPT ); Tue, 14 Mar 2023 19:33:14 -0400 Received: from mx.manguebit.com (mx.manguebit.com [167.235.159.17]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A7B7E2CFCE for ; Tue, 14 Mar 2023 16:33:12 -0700 (PDT) From: Paulo Alcantara DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=manguebit.com; s=dkim; t=1678836791; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=0ji5w3vP0ehw4Hubuf+4CIYaxb0XuD6cSbxUdz1KdVM=; b=ag/BRs3McIQZYzFj4jHwXIir9rL5rdmZO301su74/9TCkEcpn/HIXQOitE1jvgT9kSHaGm bh/aTBoZM4mzqIwIelZESOHCDoA/6wc/yUTyQQl10tqtFNlFUGBe6bf4G59BIIhkrJ5N+0 iXAWoYSJIDoGHIWsO/0hn1ppcdLbyYhBx1gaegPuu7DyaDloeVpMzxpOG8SrI5BLNvQCST FpHbdgL5KDxu8rIPyT3F2QVpI1n6+jkC/hGN848gbknrhhfflfcsdcyVC9S07hSgtHOvHU Y766tyQ5KA7Rbu6fF92lY38zfsZi6LWOGEtAQCXhL6TQTea7YbZHuooA0qFCLw== ARC-Seal: i=1; s=dkim; d=manguebit.com; t=1678836791; a=rsa-sha256; cv=none; b=gkF0ghob4Nfpx7ZFtG32igiq3gIk1yc7ULS8fL9B1thYpCrIVd+PA7AvirXrAw9Q20+F+V 8cTlujveR7vgmVTxz+Zbp1xOBfIcwPQgBu4QhjQhC9GG1A0yk8JFcvetCMFNaeMIMZWHgu Ylb8tUZeseAs69sIzsRBGd1Ne5z2lpa+orXKqvUfkyYnBRxKdTSMVMzarQZCP2fXbsu/6V pzQlfi665Rp6vtiqoLExSzNBuDrXnDX3EA74GWkpSayKhv+x2Lf6wyuf6dpIG4REk/HwvD sa4zAzwL2IxKXxapduKQPj2C0t2bfSIBFOkcjCruxLBPjDaDxLCtYZEbkTW5zQ== ARC-Authentication-Results: i=1; ORIGINATING; auth=pass smtp.auth=pc@manguebit.com smtp.mailfrom=pc@manguebit.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=manguebit.com; s=dkim; t=1678836791; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=0ji5w3vP0ehw4Hubuf+4CIYaxb0XuD6cSbxUdz1KdVM=; b=jJIGx8Wje0jgAVlxiRjyO0aoP9/qEalOTy8ekTflIqsVjKriYZMIJ3UgqdI31/pZGsx712 nXLEraqUaPKu3hZ7cwf7fnIGb+qAXQj5ZsPufoeNk+QiXd6RIu08r7zAw607hrnjNBynxY tkuq4sNpJtj5OAFl2Dco+ofaZSixDCFG63Z+oqZL1F9TLUXCsOuB2PdTj6ZIbGp2VO5PKB EAIs3iWhfblpGwR3J3ttOvWvfxtsML66qsgReS51zhHJvRiBQ0ztNR82kPlhwHLd66KjQ5 WrAXYvQqaTREN2xTzF8F8W0pWcOgbB12Q7B8YL1k8LtW7IbQu17cmZPDQ8UOZw== To: smfrench@gmail.com Cc: linux-cifs@vger.kernel.org, Paulo Alcantara Subject: [PATCH 4/4] cifs: use DFS root session instead of tcon ses Date: Tue, 14 Mar 2023 20:32:56 -0300 Message-Id: <20230314233256.16468-4-pc.crab@mail.manguebit.com> In-Reply-To: <20230314233256.16468-1-pc@manguebit.com> References: <20230314233256.16468-1-pc@manguebit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Use DFS root session whenever possible to get new DFS referrals otherwise we might end up with an IPC tcon (tcon->ses->tcon_ipc) that doesn't respond to them. It should be safe accessing @ses->dfs_root_ses directly in cifs_inval_name_dfs_link_error() as it has same lifetime as of @tcon. Signed-off-by: Paulo Alcantara (SUSE) --- fs/cifs/misc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index 6f9c78650528..b44fb51968bf 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c @@ -1262,6 +1262,7 @@ int cifs_inval_name_dfs_link_error(const unsigned int xid, * removing cached DFS targets that the client would eventually * need during failover. */ + ses = CIFS_DFS_ROOT_SES(ses); if (ses->server->ops->get_dfs_refer && !ses->server->ops->get_dfs_refer(xid, ses, ref_path, &refs, &num_refs, cifs_sb->local_nls,