From patchwork Thu Aug 17 15:33:59 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paulo Alcantara X-Patchwork-Id: 13356719 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 68560C3065E for ; Thu, 17 Aug 2023 15:36:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1352419AbjHQPfl (ORCPT ); Thu, 17 Aug 2023 11:35:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54722 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1353239AbjHQPf3 (ORCPT ); Thu, 17 Aug 2023 11:35:29 -0400 Received: from mx.manguebit.com (mx.manguebit.com [167.235.159.17]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CDFEC2D6D for ; Thu, 17 Aug 2023 08:35:27 -0700 (PDT) From: Paulo Alcantara DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=manguebit.com; s=dkim; t=1692286526; 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=5sDc5pFn6z1YkHDjOq7mz8EOz9Xku5PjOJn7NmkFYSQ=; b=LMW2rQHWZOmyBnN4q6+p6W0ROjYEX2UA5OXI57Rfyd0xbo0sgZmUcScGLPTFdZd4g+CWE9 N9ex/nWpeEQG11q+z95IdgKamsYelPWxxM1m+EtJ+dpzJdYKYGdDMn6Pw7yD/j03jpa0oY viC/hQsmFLHoqYTsmljx62mkq5IpkBwDAFN6kNJSQ56f/pIvkLPiqEJEfjRK8Qjvp/pTuM h3g+IBydGUhw/JVbUpAOZ7izAbtfY8Mt1ve3AhA5Efk0r71wHX4TfBtE8/l14IAUxHtHDS 6nednPAFIJPNJL97YuZt/VNvWKcktHbEaHjM9svwbAvLqAtcv3fKG5yzrs4TCQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=manguebit.com; s=dkim; t=1692286526; 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=5sDc5pFn6z1YkHDjOq7mz8EOz9Xku5PjOJn7NmkFYSQ=; b=aJp1yAXZPVZzCFzn4U98S646kj6B9j6qDy82a9vphZC4UwFEfMIWuW6Qp/sl0INahpfVgq 4lMmlbKfpTeTdlQ3lI6x5wYmp6tS9iEZm1ZdoLEANL+X0JzrYWzpa4sZV7RkS5q3EfWfFx Fg95bsMlpyywCsoFr3lpA936Qe6D5RuMnEfYOin2LEzR3ti6keIAnJ5zHqOPan9+GlgOuF ngIWA8iNw1pVmlgxEoZH82qkJng7jGHHLIbOP8B4auYR0vWjiX/1Kcer3gwrd0Lud7kndU WmKsdKqKEtSXtjMdtL8/Ew9w9+sGm0imyaacNg4au+SPw9qeGPSmhR6Qp/H8Jg== ARC-Authentication-Results: i=1; ORIGINATING; auth=pass smtp.auth=pc@manguebit.com smtp.mailfrom=pc@manguebit.com ARC-Seal: i=1; s=dkim; d=manguebit.com; t=1692286526; a=rsa-sha256; cv=none; b=E3+qD72Oirao4AgeQEs7lHTuVs/hTbmTV8GIsgChHgbrw3Q1FVxMBcDkpg8F753W3q9Vad BRmgh4JrkGQDoP0YgF3SOpz4DP/0E7/vzHb9AcFaNpmS1uiEpyfqHndLGimmR0JzhOoX9R 4tqWT2Z/hnx3oOk8fREyDTCFiYp++RzsFiVJDVKWrNmnvV9lWXqZBRkYjA+JSBk466CcQ1 CX+zm8TgJMy8PUM1kEsNMyHMbSSTWvyGW7Tzj+eRSvhPP2upyiSOg2PfBBmy0rEedtKOp/ FqalRqTTJYQ/pf3Z61GQhYc2O228yhtuIbcpFyhh1rAdicBdy6p/uBT77Tb/BQ== To: smfrench@gmail.com Cc: linux-cifs@vger.kernel.org, Paulo Alcantara Subject: [PATCH 01/17] smb: client: introduce DFS_CACHE_TGT_LIST() Date: Thu, 17 Aug 2023 12:33:59 -0300 Message-ID: <20230817153416.28083-2-pc@manguebit.com> In-Reply-To: <20230817153416.28083-1-pc@manguebit.com> References: <20230817153416.28083-1-pc@manguebit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Add new helper which declares and initialises target list of a DFS referral rather having to do both separately. No functional changes. Signed-off-by: Paulo Alcantara (SUSE) --- fs/smb/client/connect.c | 4 ++-- fs/smb/client/dfs.c | 6 +++--- fs/smb/client/dfs_cache.c | 4 ++-- fs/smb/client/dfs_cache.h | 6 +++++- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c index 238538dde4e3..b3461d5d0f7d 100644 --- a/fs/smb/client/connect.c +++ b/fs/smb/client/connect.c @@ -453,10 +453,10 @@ static int reconnect_target_unlocked(struct TCP_Server_Info *server, struct dfs_ static int reconnect_dfs_server(struct TCP_Server_Info *server) { - int rc = 0; - struct dfs_cache_tgt_list tl = DFS_CACHE_TGT_LIST_INIT(tl); struct dfs_cache_tgt_iterator *target_hint = NULL; + DFS_CACHE_TGT_LIST(tl); int num_targets = 0; + int rc = 0; /* * Determine the number of dfs targets the referral path in @cifs_sb resolves to. diff --git a/fs/smb/client/dfs.c b/fs/smb/client/dfs.c index ee772c3d9f00..c837800c49d4 100644 --- a/fs/smb/client/dfs.c +++ b/fs/smb/client/dfs.c @@ -174,7 +174,7 @@ static int __dfs_mount_share(struct cifs_mount_ctx *mnt_ctx) } do { - struct dfs_cache_tgt_list tl = DFS_CACHE_TGT_LIST_INIT(tl); + DFS_CACHE_TGT_LIST(tl); rc = dfs_get_referral(mnt_ctx, ref_path + 1, NULL, &tl); if (rc) { @@ -426,7 +426,7 @@ static int __tree_connect_dfs_target(const unsigned int xid, struct cifs_tcon *t /* Try to tree connect to all dfs targets */ for (; tit; tit = dfs_cache_get_next_tgt(tl, tit)) { const char *target = dfs_cache_get_tgt_name(tit); - struct dfs_cache_tgt_list ntl = DFS_CACHE_TGT_LIST_INIT(ntl); + DFS_CACHE_TGT_LIST(ntl); kfree(share); kfree(prefix); @@ -520,7 +520,7 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru int rc; struct TCP_Server_Info *server = tcon->ses->server; const struct smb_version_operations *ops = server->ops; - struct dfs_cache_tgt_list tl = DFS_CACHE_TGT_LIST_INIT(tl); + DFS_CACHE_TGT_LIST(tl); struct cifs_sb_info *cifs_sb = NULL; struct super_block *sb = NULL; struct dfs_info3_param ref = {0}; diff --git a/fs/smb/client/dfs_cache.c b/fs/smb/client/dfs_cache.c index 33adf43a01f1..89b8af831a43 100644 --- a/fs/smb/client/dfs_cache.c +++ b/fs/smb/client/dfs_cache.c @@ -1177,9 +1177,9 @@ static bool is_ses_good(struct cifs_ses *ses) /* Refresh dfs referral of tcon and mark it for reconnect if needed */ static int __refresh_tcon(const char *path, struct cifs_ses *ses, bool force_refresh) { - struct dfs_cache_tgt_list old_tl = DFS_CACHE_TGT_LIST_INIT(old_tl); - struct dfs_cache_tgt_list new_tl = DFS_CACHE_TGT_LIST_INIT(new_tl); struct TCP_Server_Info *server = ses->server; + DFS_CACHE_TGT_LIST(old_tl); + DFS_CACHE_TGT_LIST(new_tl); bool needs_refresh = false; struct cache_entry *ce; unsigned int xid; diff --git a/fs/smb/client/dfs_cache.h b/fs/smb/client/dfs_cache.h index c6d89cd6d4fd..c6abc524855f 100644 --- a/fs/smb/client/dfs_cache.h +++ b/fs/smb/client/dfs_cache.h @@ -16,7 +16,11 @@ extern struct workqueue_struct *dfscache_wq; extern atomic_t dfs_cache_ttl; -#define DFS_CACHE_TGT_LIST_INIT(var) { .tl_numtgts = 0, .tl_list = LIST_HEAD_INIT((var).tl_list), } +#define DFS_CACHE_TGT_LIST_INIT(var) \ + { .tl_numtgts = 0, .tl_list = LIST_HEAD_INIT((var).tl_list), } + +#define DFS_CACHE_TGT_LIST(var) \ + struct dfs_cache_tgt_list var = DFS_CACHE_TGT_LIST_INIT(var) struct dfs_cache_tgt_list { int tl_numtgts; From patchwork Thu Aug 17 15:34:00 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paulo Alcantara X-Patchwork-Id: 13356720 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 56582C3065B for ; Thu, 17 Aug 2023 15:36:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1352652AbjHQPfm (ORCPT ); Thu, 17 Aug 2023 11:35:42 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42642 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1353242AbjHQPfb (ORCPT ); Thu, 17 Aug 2023 11:35:31 -0400 Received: from mx.manguebit.com (mx.manguebit.com [167.235.159.17]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 668332D6D for ; Thu, 17 Aug 2023 08:35:29 -0700 (PDT) From: Paulo Alcantara DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=manguebit.com; s=dkim; t=1692286528; 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=BBUEbXV9bz9ZnmO9Vxf4Sz7qaDsxNZRQjhphLLsioVs=; b=oKEHUoSPRsZtH8+KQFBNNo/FlUKA3dAvXZ0OZ+U4nDGzDm9ExjLpY2Uan13/yxJhsA6z1c Mu7ONjz4RsVDhGWHb0uDNiUP/bb0Qp+Or5CWgRmP5rF9e/TolScFlwBOSfQBoINq+FvomX 2v1ehzxtcEmP9c8NsSR+kUr+/N94TjI2YVTJTAXRW72Lwmgr5DQDETzCD6z7dy8olYlsrm TugH2E+xqyv5pvi7bUm0Hu3xqt6ChDsOQteRTi5Ql6PMphP4Ai3ytEPpxFnCio30o1Xy4X gR0SVxk0K3eIrCSEkJra/XAO9Zmvw0RF7GkyH071Gavu+ePOTyb3CWSq4m82Hg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=manguebit.com; s=dkim; t=1692286528; 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=BBUEbXV9bz9ZnmO9Vxf4Sz7qaDsxNZRQjhphLLsioVs=; b=S8ptd85FRWAHDqkwU2j3Wu/f1jK+n0iw5MbnFnCSTfOCJgY8Lalurr4KC3cXc7kEzGS2xf 73zEiV0UTWZaUYv/5g5PC24lSsgAu91jYLoKz1BYTZXbTUYs7cKBw50qvnd2pQN/Ka4ly5 c2Uvn4YQpXFq18ICzRIWjB6n0AEWZK7pBvyWTW82rxehyeFDkODk5C9Z0yvBiLv66gU3Wq hAXcFsEBQJZmLy922VzplFVTw7ZupiRaF9dnCOJc+fU4cCnzQgEjitH4f76gJV8Asx66OF a4dD7rCEW7+so1GezzbqbHZLp9o2xJKZrF3YaLJrlcdyTPaJ0NrC25g32PkqgA== ARC-Authentication-Results: i=1; ORIGINATING; auth=pass smtp.auth=pc@manguebit.com smtp.mailfrom=pc@manguebit.com ARC-Seal: i=1; s=dkim; d=manguebit.com; t=1692286528; a=rsa-sha256; cv=none; b=NhD7J672of9gJYGV/nxnQIT1xOvZhpk0lhg9jcMW6g4h7HHpB40SPpN8rTpJsNFRXxJsy9 SSzrRodFpwZ0DcHbCg3RPk5rfQXLqqkPD5gvOvmoDpGBTJ7bD7VxzVa9OuwaTNYNZzuo0+ Gf4NWjHoXO8XRv3Bd5LzZYB3nujbWyqYJHYLHJwAJ9bcRMdBNbIc5n/Yn4bKMwwebekaeg JIl2xAOtzciHsjlTcStpobwEfx9G6mipcj4K0QhswrxMM9Z+nxY9kxaEzhod1EAgvbRzNd wg7i3KNHwKqfnKbiKjaYJiSsP38C/ZET95IvN60cZwndFm1W6h59ZmjRa862Tw== To: smfrench@gmail.com Cc: linux-cifs@vger.kernel.org, Paulo Alcantara Subject: [PATCH 02/17] smb: client: ensure to try all targets when finding nested links Date: Thu, 17 Aug 2023 12:34:00 -0300 Message-ID: <20230817153416.28083-3-pc@manguebit.com> In-Reply-To: <20230817153416.28083-1-pc@manguebit.com> References: <20230817153416.28083-1-pc@manguebit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org With current implementation, when a nested DFS link is found during mount(2), the client follows the referral and then try to connect to all of its targets. If all targets failed, the client bails out rather than retrying remaining targets from previous referral. Fix this by stacking all referrals and targets so the client can retry remaining targets from previous referrals in case all targets of current referral have failed. Thanks to samba, this can be easily tested like below * Run the following under dfs folder in samba server $ ln -s "msdfs:srv\\bad-share" link1 $ ln -s "msdfs:srv\\dfs\\link1,srv\\good-share" link0 * Before patch $ mount.cifs //srv/dfs/link0 /mnt -o ... mount error(2): No such file or directory Refer to the mount.cifs(8) manual page (e.g. man mount.cifs)... * After patch $ mount.cifs //srv/dfs/link0 /mnt -o ... # ls /mnt bar fileshare1 sub Signed-off-by: Paulo Alcantara (SUSE) --- fs/smb/client/cifsglob.h | 16 ++- fs/smb/client/dfs.c | 271 ++++++++++++++++++++------------------ fs/smb/client/dfs.h | 104 +++++++++++++++ fs/smb/client/dfs_cache.c | 6 +- fs/smb/client/dfs_cache.h | 6 +- 5 files changed, 265 insertions(+), 138 deletions(-) diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h index 657dee4b2c8c..712557c2d526 100644 --- a/fs/smb/client/cifsglob.h +++ b/fs/smb/client/cifsglob.h @@ -1721,11 +1721,23 @@ struct cifs_mount_ctx { struct list_head dfs_ses_list; }; +static inline void __free_dfs_info_param(struct dfs_info3_param *param) +{ + kfree(param->path_name); + kfree(param->node_name); +} + static inline void free_dfs_info_param(struct dfs_info3_param *param) +{ + if (param) + __free_dfs_info_param(param); +} + +static inline void zfree_dfs_info_param(struct dfs_info3_param *param) { if (param) { - kfree(param->path_name); - kfree(param->node_name); + __free_dfs_info_param(param); + memset(param, 0, sizeof(*param)); } } diff --git a/fs/smb/client/dfs.c b/fs/smb/client/dfs.c index c837800c49d4..71ee74041884 100644 --- a/fs/smb/client/dfs.c +++ b/fs/smb/client/dfs.c @@ -3,7 +3,6 @@ * Copyright (c) 2022 Paulo Alcantara */ -#include #include "cifsproto.h" #include "cifs_debug.h" #include "dns_resolve.h" @@ -96,51 +95,134 @@ static int add_root_smb_session(struct cifs_mount_ctx *mnt_ctx) return 0; } -static int get_dfs_conn(struct cifs_mount_ctx *mnt_ctx, const char *ref_path, const char *full_path, - const struct dfs_cache_tgt_iterator *tit) +static inline int parse_dfs_target(struct smb3_fs_context *ctx, + struct dfs_ref_walk *rw, + struct dfs_info3_param *tgt) +{ + int rc; + const char *fpath = ref_walk_fpath(rw) + 1; + + rc = ref_walk_get_tgt(rw, tgt); + if (!rc) + rc = dfs_parse_target_referral(fpath, tgt, ctx); + return rc; +} + +static int set_ref_paths(struct cifs_mount_ctx *mnt_ctx, + struct dfs_info3_param *tgt, + struct dfs_ref_walk *rw) +{ + struct smb3_fs_context *ctx = mnt_ctx->fs_ctx; + struct cifs_sb_info *cifs_sb = mnt_ctx->cifs_sb; + char *ref_path, *full_path; + int rc; + + full_path = smb3_fs_context_fullpath(ctx, CIFS_DIR_SEP(cifs_sb)); + if (IS_ERR(full_path)) + return PTR_ERR(full_path); + + if (!tgt || (tgt->server_type == DFS_TYPE_LINK && + DFS_INTERLINK(tgt->flags))) + ref_path = dfs_get_path(cifs_sb, ctx->UNC); + else + ref_path = dfs_get_path(cifs_sb, full_path); + if (IS_ERR(ref_path)) { + rc = PTR_ERR(ref_path); + kfree(full_path); + return rc; + } + ref_walk_path(rw) = ref_path; + ref_walk_fpath(rw) = full_path; + return 0; +} + +static int __dfs_referral_walk(struct cifs_mount_ctx *mnt_ctx, + struct dfs_ref_walk *rw) { struct smb3_fs_context *ctx = mnt_ctx->fs_ctx; - struct dfs_info3_param ref = {}; + struct dfs_info3_param tgt = {}; bool is_refsrv; - int rc, rc2; - - rc = dfs_cache_get_tgt_referral(ref_path + 1, tit, &ref); - if (rc) - return rc; - - rc = dfs_parse_target_referral(full_path + 1, &ref, ctx); - if (rc) - goto out; - - cifs_mount_put_conns(mnt_ctx); - rc = get_session(mnt_ctx, ref_path); - if (rc) - goto out; - - is_refsrv = !!(ref.flags & DFSREF_REFERRAL_SERVER); - - rc = -EREMOTE; - if (ref.flags & DFSREF_STORAGE_SERVER) { - rc = cifs_mount_get_tcon(mnt_ctx); - if (rc) - goto out; - - /* some servers may not advertise referral capability under ref.flags */ - is_refsrv |= is_tcon_dfs(mnt_ctx->tcon); - - rc = cifs_is_path_remote(mnt_ctx); - } - - dfs_cache_noreq_update_tgthint(ref_path + 1, tit); - - if (rc == -EREMOTE && is_refsrv) { - rc2 = add_root_smb_session(mnt_ctx); - if (rc2) - rc = rc2; - } + int rc = -ENOENT; + +again: + do { + if (ref_walk_empty(rw)) { + rc = dfs_get_referral(mnt_ctx, ref_walk_path(rw) + 1, + NULL, ref_walk_tl(rw)); + if (rc) { + rc = cifs_mount_get_tcon(mnt_ctx); + if (!rc) + rc = cifs_is_path_remote(mnt_ctx); + continue; + } + if (!ref_walk_num_tgts(rw)) { + rc = -ENOENT; + continue; + } + } + + while (ref_walk_next_tgt(rw)) { + rc = parse_dfs_target(ctx, rw, &tgt); + if (rc) + continue; + + cifs_mount_put_conns(mnt_ctx); + rc = get_session(mnt_ctx, ref_walk_path(rw)); + if (rc) + continue; + + is_refsrv = tgt.server_type == DFS_TYPE_ROOT || + DFS_INTERLINK(tgt.flags); + ref_walk_set_tgt_hint(rw); + + if (tgt.flags & DFSREF_STORAGE_SERVER) { + rc = cifs_mount_get_tcon(mnt_ctx); + if (!rc) + rc = cifs_is_path_remote(mnt_ctx); + if (!rc) + break; + if (rc != -EREMOTE) + continue; + } + + if (is_refsrv) { + rc = add_root_smb_session(mnt_ctx); + if (rc) + goto out; + } + + rc = ref_walk_advance(rw); + if (!rc) { + rc = set_ref_paths(mnt_ctx, &tgt, rw); + if (!rc) { + rc = -EREMOTE; + goto again; + } + } + if (rc != -ELOOP) + goto out; + } + } while (rc && ref_walk_descend(rw)); out: - free_dfs_info_param(&ref); + free_dfs_info_param(&tgt); + return rc; +} + +static int dfs_referral_walk(struct cifs_mount_ctx *mnt_ctx) +{ + struct dfs_ref_walk *rw; + int rc; + + rw = ref_walk_alloc(); + if (IS_ERR(rw)) + return PTR_ERR(rw); + + ref_walk_init(rw); + rc = set_ref_paths(mnt_ctx, NULL, rw); + if (!rc) + rc = __dfs_referral_walk(mnt_ctx, rw); + ref_walk_free(rw); return rc; } @@ -148,105 +230,36 @@ static int __dfs_mount_share(struct cifs_mount_ctx *mnt_ctx) { struct cifs_sb_info *cifs_sb = mnt_ctx->cifs_sb; struct smb3_fs_context *ctx = mnt_ctx->fs_ctx; - char *ref_path = NULL, *full_path = NULL; - struct dfs_cache_tgt_iterator *tit; struct cifs_tcon *tcon; - char *origin_fullpath = NULL; - char sep = CIFS_DIR_SEP(cifs_sb); - int num_links = 0; + char *origin_fullpath; int rc; - ref_path = dfs_get_path(cifs_sb, ctx->UNC); - if (IS_ERR(ref_path)) - return PTR_ERR(ref_path); + origin_fullpath = dfs_get_path(cifs_sb, ctx->source); + if (IS_ERR(origin_fullpath)) + return PTR_ERR(origin_fullpath); - full_path = smb3_fs_context_fullpath(ctx, sep); - if (IS_ERR(full_path)) { - rc = PTR_ERR(full_path); - full_path = NULL; + rc = dfs_referral_walk(mnt_ctx); + if (rc) goto out; - } - origin_fullpath = kstrdup(full_path, GFP_KERNEL); - if (!origin_fullpath) { - rc = -ENOMEM; - goto out; + tcon = mnt_ctx->tcon; + spin_lock(&tcon->tc_lock); + if (!tcon->origin_fullpath) { + tcon->origin_fullpath = origin_fullpath; + origin_fullpath = NULL; } - - do { - DFS_CACHE_TGT_LIST(tl); - - rc = dfs_get_referral(mnt_ctx, ref_path + 1, NULL, &tl); - if (rc) { - rc = cifs_mount_get_tcon(mnt_ctx); - if (!rc) - rc = cifs_is_path_remote(mnt_ctx); - break; - } - - tit = dfs_cache_get_tgt_iterator(&tl); - if (!tit) { - cifs_dbg(VFS, "%s: dfs referral (%s) with no targets\n", __func__, - ref_path + 1); - rc = -ENOENT; - dfs_cache_free_tgts(&tl); - break; - } - - do { - rc = get_dfs_conn(mnt_ctx, ref_path, full_path, tit); - if (!rc) - break; - if (rc == -EREMOTE) { - if (++num_links > MAX_NESTED_LINKS) { - rc = -ELOOP; - break; - } - kfree(ref_path); - kfree(full_path); - ref_path = full_path = NULL; - - full_path = smb3_fs_context_fullpath(ctx, sep); - if (IS_ERR(full_path)) { - rc = PTR_ERR(full_path); - full_path = NULL; - } else { - ref_path = dfs_get_path(cifs_sb, full_path); - if (IS_ERR(ref_path)) { - rc = PTR_ERR(ref_path); - ref_path = NULL; - } - } - break; - } - } while ((tit = dfs_cache_get_next_tgt(&tl, tit))); - dfs_cache_free_tgts(&tl); - } while (rc == -EREMOTE); - - if (!rc) { - tcon = mnt_ctx->tcon; - - spin_lock(&tcon->tc_lock); - if (!tcon->origin_fullpath) { - tcon->origin_fullpath = origin_fullpath; - origin_fullpath = NULL; - } - spin_unlock(&tcon->tc_lock); - - if (list_empty(&tcon->dfs_ses_list)) { - list_replace_init(&mnt_ctx->dfs_ses_list, - &tcon->dfs_ses_list); - queue_delayed_work(dfscache_wq, &tcon->dfs_cache_work, - dfs_cache_get_ttl() * HZ); - } else { - dfs_put_root_smb_sessions(&mnt_ctx->dfs_ses_list); - } + spin_unlock(&tcon->tc_lock); + + if (list_empty(&tcon->dfs_ses_list)) { + list_replace_init(&mnt_ctx->dfs_ses_list, &tcon->dfs_ses_list); + queue_delayed_work(dfscache_wq, &tcon->dfs_cache_work, + dfs_cache_get_ttl() * HZ); + } else { + dfs_put_root_smb_sessions(&mnt_ctx->dfs_ses_list); } out: kfree(origin_fullpath); - kfree(ref_path); - kfree(full_path); return rc; } diff --git a/fs/smb/client/dfs.h b/fs/smb/client/dfs.h index 98e9d2aca6a7..c0a9eea6a2c5 100644 --- a/fs/smb/client/dfs.h +++ b/fs/smb/client/dfs.h @@ -9,6 +9,110 @@ #include "cifsglob.h" #include "fs_context.h" #include "cifs_unicode.h" +#include + +#define DFS_INTERLINK(v) \ + (((v) & DFSREF_REFERRAL_SERVER) && !((v) & DFSREF_STORAGE_SERVER)) + +struct dfs_ref { + char *path; + char *full_path; + struct dfs_cache_tgt_list tl; + struct dfs_cache_tgt_iterator *tit; +}; + +struct dfs_ref_walk { + struct dfs_ref *ref; + struct dfs_ref refs[MAX_NESTED_LINKS]; +}; + +#define ref_walk_start(w) ((w)->refs) +#define ref_walk_end(w) (&(w)->refs[ARRAY_SIZE((w)->refs) - 1]) +#define ref_walk_cur(w) ((w)->ref) +#define ref_walk_descend(w) (--ref_walk_cur(w) >= ref_walk_start(w)) + +#define ref_walk_tit(w) (ref_walk_cur(w)->tit) +#define ref_walk_empty(w) (!ref_walk_tit(w)) +#define ref_walk_path(w) (ref_walk_cur(w)->path) +#define ref_walk_fpath(w) (ref_walk_cur(w)->full_path) +#define ref_walk_tl(w) (&ref_walk_cur(w)->tl) + +static inline struct dfs_ref_walk *ref_walk_alloc(void) +{ + struct dfs_ref_walk *rw; + + rw = kmalloc(sizeof(*rw), GFP_KERNEL); + if (!rw) + return ERR_PTR(-ENOMEM); + return rw; +} + +static inline void ref_walk_init(struct dfs_ref_walk *rw) +{ + memset(rw, 0, sizeof(*rw)); + ref_walk_cur(rw) = ref_walk_start(rw); +} + +static inline void __ref_walk_free(struct dfs_ref *ref) +{ + kfree(ref->path); + kfree(ref->full_path); + dfs_cache_free_tgts(&ref->tl); + memset(ref, 0, sizeof(*ref)); +} + +static inline void ref_walk_free(struct dfs_ref_walk *rw) +{ + struct dfs_ref *ref = ref_walk_start(rw); + + for (; ref <= ref_walk_end(rw); ref++) + __ref_walk_free(ref); + kfree(rw); +} + +static inline int ref_walk_advance(struct dfs_ref_walk *rw) +{ + struct dfs_ref *ref = ref_walk_cur(rw) + 1; + + if (ref > ref_walk_end(rw)) + return -ELOOP; + __ref_walk_free(ref); + ref_walk_cur(rw) = ref; + return 0; +} + +static inline struct dfs_cache_tgt_iterator * +ref_walk_next_tgt(struct dfs_ref_walk *rw) +{ + struct dfs_cache_tgt_iterator *tit; + struct dfs_ref *ref = ref_walk_cur(rw); + + if (!ref->tit) + tit = dfs_cache_get_tgt_iterator(&ref->tl); + else + tit = dfs_cache_get_next_tgt(&ref->tl, ref->tit); + ref->tit = tit; + return tit; +} + +static inline int ref_walk_get_tgt(struct dfs_ref_walk *rw, + struct dfs_info3_param *tgt) +{ + zfree_dfs_info_param(tgt); + return dfs_cache_get_tgt_referral(ref_walk_path(rw) + 1, + ref_walk_tit(rw), tgt); +} + +static inline int ref_walk_num_tgts(struct dfs_ref_walk *rw) +{ + return dfs_cache_get_nr_tgts(ref_walk_tl(rw)); +} + +static inline void ref_walk_set_tgt_hint(struct dfs_ref_walk *rw) +{ + dfs_cache_noreq_update_tgthint(ref_walk_path(rw) + 1, + ref_walk_tit(rw)); +} struct dfs_root_ses { struct list_head list; diff --git a/fs/smb/client/dfs_cache.c b/fs/smb/client/dfs_cache.c index 89b8af831a43..508d831fabe3 100644 --- a/fs/smb/client/dfs_cache.c +++ b/fs/smb/client/dfs_cache.c @@ -29,8 +29,6 @@ #define CACHE_MIN_TTL 120 /* 2 minutes */ #define CACHE_DEFAULT_TTL 300 /* 5 minutes */ -#define IS_DFS_INTERLINK(v) (((v) & DFSREF_REFERRAL_SERVER) && !((v) & DFSREF_STORAGE_SERVER)) - struct cache_dfs_tgt { char *name; int path_consumed; @@ -174,7 +172,7 @@ static int dfscache_proc_show(struct seq_file *m, void *v) "cache entry: path=%s,type=%s,ttl=%d,etime=%ld,hdr_flags=0x%x,ref_flags=0x%x,interlink=%s,path_consumed=%d,expired=%s\n", ce->path, ce->srvtype == DFS_TYPE_ROOT ? "root" : "link", ce->ttl, ce->etime.tv_nsec, ce->hdr_flags, ce->ref_flags, - IS_DFS_INTERLINK(ce->hdr_flags) ? "yes" : "no", + DFS_INTERLINK(ce->hdr_flags) ? "yes" : "no", ce->path_consumed, cache_entry_expired(ce) ? "yes" : "no"); list_for_each_entry(t, &ce->tlist, list) { @@ -243,7 +241,7 @@ static inline void dump_ce(const struct cache_entry *ce) ce->srvtype == DFS_TYPE_ROOT ? "root" : "link", ce->ttl, ce->etime.tv_nsec, ce->hdr_flags, ce->ref_flags, - IS_DFS_INTERLINK(ce->hdr_flags) ? "yes" : "no", + DFS_INTERLINK(ce->hdr_flags) ? "yes" : "no", ce->path_consumed, cache_entry_expired(ce) ? "yes" : "no"); dump_tgts(ce); diff --git a/fs/smb/client/dfs_cache.h b/fs/smb/client/dfs_cache.h index c6abc524855f..18a08a2ca93b 100644 --- a/fs/smb/client/dfs_cache.h +++ b/fs/smb/client/dfs_cache.h @@ -55,8 +55,8 @@ static inline struct dfs_cache_tgt_iterator * dfs_cache_get_next_tgt(struct dfs_cache_tgt_list *tl, struct dfs_cache_tgt_iterator *it) { - if (!tl || list_empty(&tl->tl_list) || !it || - list_is_last(&it->it_list, &tl->tl_list)) + if (!tl || !tl->tl_numtgts || list_empty(&tl->tl_list) || + !it || list_is_last(&it->it_list, &tl->tl_list)) return NULL; return list_next_entry(it, it_list); } @@ -75,7 +75,7 @@ static inline void dfs_cache_free_tgts(struct dfs_cache_tgt_list *tl) { struct dfs_cache_tgt_iterator *it, *nit; - if (!tl || list_empty(&tl->tl_list)) + if (!tl || !tl->tl_numtgts || list_empty(&tl->tl_list)) return; list_for_each_entry_safe(it, nit, &tl->tl_list, it_list) { list_del(&it->it_list); From patchwork Thu Aug 17 15:34:01 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paulo Alcantara X-Patchwork-Id: 13356717 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 EE678C3065A for ; Thu, 17 Aug 2023 15:36:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1352325AbjHQPfl (ORCPT ); Thu, 17 Aug 2023 11:35:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42662 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1352419AbjHQPfd (ORCPT ); Thu, 17 Aug 2023 11:35:33 -0400 Received: from mx.manguebit.com (mx.manguebit.com [IPv6:2a01:4f8:1c1e:a2ae::2]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 62FC730D1 for ; Thu, 17 Aug 2023 08:35:31 -0700 (PDT) From: Paulo Alcantara DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=manguebit.com; s=dkim; t=1692286529; 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=TA7u0WoopLEa7a4Pd8C8cxs5u/xTPlq/mWW6rsmRnok=; b=rnXgELluKyHavPT0ZK1UeN8C6JaGkSBFhnLFcnIppVTD/5SGCjUEiSZJByuO0wKsvJGvZJ FnDC8J2T2h3DbWqE2jKkFiwSjZaUrWjtgiFwF1Umv5q9K0R0uADDXGkYhV8dcDNYj0msjq 8X4tkaN0oKUsxqqyYg26BwPpWYCmXqSW2G4YyjWWwkhHKDWu6fzrpSIU6j92iEElJ8yP56 Sk+WIJW5zJh5k7t6+3tM/3/7i9uHu4bR6Thvzg2Vy7Lp7LoeArgKfTNsuIL/ft0galOG0X uDsSAgZ1uQtTXC8LBYOvT0G1WTVV2xlQwb4VO6lPy9g2+0HEi1PZGnktV7jG4w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=manguebit.com; s=dkim; t=1692286529; 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=TA7u0WoopLEa7a4Pd8C8cxs5u/xTPlq/mWW6rsmRnok=; b=nAlKaE9CKefUyx310haa/XVQRWOnPFDuQLUOPMZWV8FD8FKMoMfLrWzfFxLJ5seTfJ5vYJ Y1ongdCM3Q0GveoKXrQp18JximTxYIpKoHvk8UgOotWW8Pe6L/YriVrv5szymj9+vbx9Xo zar0aTw5ck1zJkUI8j5w6dtFBlxcD6MOtCswv6fIlqS8mOwodU4MMYJqqdeDtDjDbXHORY W+JdvQABwxWBMPRyMtpS2TxbD53tU+MNyDgYsRB05alL1a6btI2K9leDgJfSf0plHG9u2l d0AYga0tlzpErU6EnpmX6Z48yTmNGX8kLAGn71g0FVh41VuWWFRHa2dCpnAyXg== ARC-Authentication-Results: i=1; ORIGINATING; auth=pass smtp.auth=pc@manguebit.com smtp.mailfrom=pc@manguebit.com ARC-Seal: i=1; s=dkim; d=manguebit.com; t=1692286529; a=rsa-sha256; cv=none; b=WLmMk6Fos0VQkxe6aNNb3YBNP3p/5r5H3626TgsC4Dpfq7bq2PfRqrAxQDohHsQ9/RHa9u kPsQ8UnekhDONdAH9xT5xwA1Imj7hQurj0KGBhXr48IcoUShZM5FxK9YDuEd9Cr98+Q7/u 23PVtzmVDMIXW5cABVORtAhFoI5PrgI6dmRJvdxWY24Ky1iq7sNc8rNG5M+8XtDl7cJzKB mpO4LDK+WvYt4W44qKScZ3q63dfH5//EvVk3bpfl+JM1nzKErdJfnPn3rWYliHcBuzPfLs Z8+GEaI5+Vp3Zz42rhitC7HiKC4eTrT9YhQSEmSHlckI9du/PMheonP6ykUZhw== To: smfrench@gmail.com Cc: linux-cifs@vger.kernel.org, Paulo Alcantara Subject: [PATCH 03/17] smb: client: move some params to cifs_open_info_data Date: Thu, 17 Aug 2023 12:34:01 -0300 Message-ID: <20230817153416.28083-4-pc@manguebit.com> In-Reply-To: <20230817153416.28083-1-pc@manguebit.com> References: <20230817153416.28083-1-pc@manguebit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Instead of passing @adjust_tz and some reparse point related fields as parameters in ->query_path_info() and {smb311_posix,cifs}_info_to_fattr() calls, move them to cifs_open_info_data structure as they can be easily accessed through @data. No functional changes. Signed-off-by: Paulo Alcantara (SUSE) --- fs/smb/client/cifsglob.h | 14 ++++++-- fs/smb/client/inode.c | 68 ++++++++++++++++++--------------------- fs/smb/client/smb1ops.c | 15 +++++---- fs/smb/client/smb2inode.c | 29 +++++++++-------- fs/smb/client/smb2proto.h | 17 ++++++---- 5 files changed, 77 insertions(+), 66 deletions(-) diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h index 712557c2d526..4792de20a447 100644 --- a/fs/smb/client/cifsglob.h +++ b/fs/smb/client/cifsglob.h @@ -186,6 +186,12 @@ struct cifs_cred { }; struct cifs_open_info_data { + bool adjust_tz; + union { + bool reparse_point; + bool symlink; + }; + __u32 reparse_tag; char *symlink_target; union { struct smb2_file_all_info fi; @@ -318,9 +324,11 @@ struct smb_version_operations { int (*is_path_accessible)(const unsigned int, struct cifs_tcon *, struct cifs_sb_info *, const char *); /* query path data from the server */ - int (*query_path_info)(const unsigned int xid, struct cifs_tcon *tcon, - struct cifs_sb_info *cifs_sb, const char *full_path, - struct cifs_open_info_data *data, bool *adjust_tz, bool *reparse); + int (*query_path_info)(const unsigned int xid, + struct cifs_tcon *tcon, + struct cifs_sb_info *cifs_sb, + const char *full_path, + struct cifs_open_info_data *data); /* query file data from the server */ int (*query_file_info)(const unsigned int xid, struct cifs_tcon *tcon, struct cifsFileInfo *cfile, struct cifs_open_info_data *data); diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c index c3eeae07e139..0d11e63042e2 100644 --- a/fs/smb/client/inode.c +++ b/fs/smb/client/inode.c @@ -632,10 +632,11 @@ static int cifs_sfu_mode(struct cifs_fattr *fattr, const unsigned char *path, } /* Fill a cifs_fattr struct with info from POSIX info struct */ -static void smb311_posix_info_to_fattr(struct cifs_fattr *fattr, struct cifs_open_info_data *data, +static void smb311_posix_info_to_fattr(struct cifs_fattr *fattr, + struct cifs_open_info_data *data, struct cifs_sid *owner, struct cifs_sid *group, - struct super_block *sb, bool adjust_tz, bool symlink) + struct super_block *sb) { struct smb311_posix_qinfo *info = &data->posix_fi; struct cifs_sb_info *cifs_sb = CIFS_SB(sb); @@ -655,7 +656,7 @@ static void smb311_posix_info_to_fattr(struct cifs_fattr *fattr, struct cifs_ope fattr->cf_ctime = cifs_NTtimeToUnix(info->ChangeTime); fattr->cf_mtime = cifs_NTtimeToUnix(info->LastWriteTime); - if (adjust_tz) { + if (data->adjust_tz) { fattr->cf_ctime.tv_sec += tcon->ses->server->timeAdj; fattr->cf_mtime.tv_sec += tcon->ses->server->timeAdj; } @@ -669,7 +670,7 @@ static void smb311_posix_info_to_fattr(struct cifs_fattr *fattr, struct cifs_ope /* The srv fs device id is overridden on network mount so setting rdev isn't needed here */ /* fattr->cf_rdev = le32_to_cpu(info->DeviceId); */ - if (symlink) { + if (data->symlink) { fattr->cf_mode |= S_IFLNK; fattr->cf_dtype = DT_LNK; fattr->cf_symlink_target = data->symlink_target; @@ -690,13 +691,14 @@ static void smb311_posix_info_to_fattr(struct cifs_fattr *fattr, struct cifs_ope fattr->cf_mode, fattr->cf_uniqueid, fattr->cf_nlink); } -static void cifs_open_info_to_fattr(struct cifs_fattr *fattr, struct cifs_open_info_data *data, - struct super_block *sb, bool adjust_tz, bool symlink, - u32 reparse_tag) +static void cifs_open_info_to_fattr(struct cifs_fattr *fattr, + struct cifs_open_info_data *data, + struct super_block *sb) { struct smb2_file_all_info *info = &data->fi; struct cifs_sb_info *cifs_sb = CIFS_SB(sb); struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); + u32 reparse_tag = data->reparse_tag; memset(fattr, 0, sizeof(*fattr)); fattr->cf_cifsattrs = le32_to_cpu(info->Attributes); @@ -711,7 +713,7 @@ static void cifs_open_info_to_fattr(struct cifs_fattr *fattr, struct cifs_open_i fattr->cf_ctime = cifs_NTtimeToUnix(info->ChangeTime); fattr->cf_mtime = cifs_NTtimeToUnix(info->LastWriteTime); - if (adjust_tz) { + if (data->adjust_tz) { fattr->cf_ctime.tv_sec += tcon->ses->server->timeAdj; fattr->cf_mtime.tv_sec += tcon->ses->server->timeAdj; } @@ -736,7 +738,7 @@ static void cifs_open_info_to_fattr(struct cifs_fattr *fattr, struct cifs_open_i } else if (reparse_tag == IO_REPARSE_TAG_LX_BLK) { fattr->cf_mode |= S_IFBLK | cifs_sb->ctx->file_mode; fattr->cf_dtype = DT_BLK; - } else if (symlink || reparse_tag == IO_REPARSE_TAG_SYMLINK || + } else if (data->symlink || reparse_tag == IO_REPARSE_TAG_SYMLINK || reparse_tag == IO_REPARSE_TAG_NFS) { fattr->cf_mode = S_IFLNK; fattr->cf_dtype = DT_LNK; @@ -789,8 +791,6 @@ cifs_get_file_info(struct file *filp) struct cifsFileInfo *cfile = filp->private_data; struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); struct TCP_Server_Info *server = tcon->ses->server; - bool symlink = false; - u32 tag = 0; if (!server->ops->query_file_info) return -ENOSYS; @@ -800,11 +800,12 @@ cifs_get_file_info(struct file *filp) switch (rc) { case 0: /* TODO: add support to query reparse tag */ + data.adjust_tz = false; if (data.symlink_target) { - symlink = true; - tag = IO_REPARSE_TAG_SYMLINK; + data.symlink = true; + data.reparse_tag = IO_REPARSE_TAG_SYMLINK; } - cifs_open_info_to_fattr(&fattr, &data, inode->i_sb, false, symlink, tag); + cifs_open_info_to_fattr(&fattr, &data, inode->i_sb); break; case -EREMOTE: cifs_create_dfs_fattr(&fattr, inode->i_sb); @@ -968,14 +969,11 @@ int cifs_get_inode_info(struct inode **inode, const char *full_path, struct TCP_Server_Info *server; struct tcon_link *tlink; struct cifs_sb_info *cifs_sb = CIFS_SB(sb); - bool adjust_tz = false; struct cifs_fattr fattr = {0}; - bool is_reparse_point = false; struct cifs_open_info_data tmp_data = {}; void *smb1_backup_rsp_buf = NULL; int rc = 0; int tmprc = 0; - __u32 reparse_tag = 0; tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) @@ -992,8 +990,8 @@ int cifs_get_inode_info(struct inode **inode, const char *full_path, cifs_dbg(FYI, "No need to revalidate cached inode sizes\n"); goto out; } - rc = server->ops->query_path_info(xid, tcon, cifs_sb, full_path, &tmp_data, - &adjust_tz, &is_reparse_point); + rc = server->ops->query_path_info(xid, tcon, cifs_sb, + full_path, &tmp_data); data = &tmp_data; } @@ -1008,24 +1006,23 @@ int cifs_get_inode_info(struct inode **inode, const char *full_path, * since we have to check if its reparse tag matches a known * special file type e.g. symlink or fifo or char etc. */ - if (is_reparse_point && data->symlink_target) { - reparse_tag = IO_REPARSE_TAG_SYMLINK; + if (data->reparse_point && data->symlink_target) { + data->reparse_tag = IO_REPARSE_TAG_SYMLINK; } else if ((le32_to_cpu(data->fi.Attributes) & ATTR_REPARSE) && server->ops->query_reparse_tag) { tmprc = server->ops->query_reparse_tag(xid, tcon, cifs_sb, full_path, - &reparse_tag); - if (tmprc) - cifs_dbg(FYI, "%s: query_reparse_tag: rc = %d\n", __func__, tmprc); + &data->reparse_tag); + cifs_dbg(FYI, "%s: query_reparse_tag: rc = %d\n", __func__, tmprc); if (server->ops->query_symlink) { - tmprc = server->ops->query_symlink(xid, tcon, cifs_sb, full_path, + tmprc = server->ops->query_symlink(xid, tcon, cifs_sb, + full_path, &data->symlink_target, - is_reparse_point); - if (tmprc) - cifs_dbg(FYI, "%s: query_symlink: rc = %d\n", __func__, - tmprc); + data->reparse_point); + cifs_dbg(FYI, "%s: query_symlink: rc = %d\n", + __func__, tmprc); } } - cifs_open_info_to_fattr(&fattr, data, sb, adjust_tz, is_reparse_point, reparse_tag); + cifs_open_info_to_fattr(&fattr, data, sb); break; case -EREMOTE: /* DFS link, no metadata available on this server */ @@ -1168,9 +1165,7 @@ smb311_posix_get_inode_info(struct inode **inode, struct cifs_tcon *tcon; struct tcon_link *tlink; struct cifs_sb_info *cifs_sb = CIFS_SB(sb); - bool adjust_tz = false; struct cifs_fattr fattr = {0}; - bool symlink = false; struct cifs_open_info_data data = {}; struct cifs_sid owner, group; int rc = 0; @@ -1190,9 +1185,9 @@ smb311_posix_get_inode_info(struct inode **inode, goto out; } - rc = smb311_posix_query_path_info(xid, tcon, cifs_sb, full_path, &data, - &owner, &group, &adjust_tz, - &symlink); + rc = smb311_posix_query_path_info(xid, tcon, cifs_sb, + full_path, &data, + &owner, &group); /* * 2. Convert it to internal cifs metadata (fattr) @@ -1200,8 +1195,7 @@ smb311_posix_get_inode_info(struct inode **inode, switch (rc) { case 0: - smb311_posix_info_to_fattr(&fattr, &data, &owner, &group, - sb, adjust_tz, symlink); + smb311_posix_info_to_fattr(&fattr, &data, &owner, &group, sb); break; case -EREMOTE: /* DFS link, no metadata available on this server */ diff --git a/fs/smb/client/smb1ops.c b/fs/smb/client/smb1ops.c index 7d1b3fc014d9..094ef4fe2219 100644 --- a/fs/smb/client/smb1ops.c +++ b/fs/smb/client/smb1ops.c @@ -542,14 +542,17 @@ cifs_is_path_accessible(const unsigned int xid, struct cifs_tcon *tcon, return rc; } -static int cifs_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, - struct cifs_sb_info *cifs_sb, const char *full_path, - struct cifs_open_info_data *data, bool *adjustTZ, bool *symlink) +static int cifs_query_path_info(const unsigned int xid, + struct cifs_tcon *tcon, + struct cifs_sb_info *cifs_sb, + const char *full_path, + struct cifs_open_info_data *data) { int rc; FILE_ALL_INFO fi = {}; - *symlink = false; + data->symlink = false; + data->adjust_tz = false; /* could do find first instead but this returns more info */ rc = CIFSSMBQPathInfo(xid, tcon, full_path, &fi, 0 /* not legacy */, cifs_sb->local_nls, @@ -562,7 +565,7 @@ static int cifs_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, if ((rc == -EOPNOTSUPP) || (rc == -EINVAL)) { rc = SMBQueryInformation(xid, tcon, full_path, &fi, cifs_sb->local_nls, cifs_remap(cifs_sb)); - *adjustTZ = true; + data->adjust_tz = true; } if (!rc) { @@ -589,7 +592,7 @@ static int cifs_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, /* Need to check if this is a symbolic link or not */ tmprc = CIFS_open(xid, &oparms, &oplock, NULL); if (tmprc == -EOPNOTSUPP) - *symlink = true; + data->symlink = true; else if (tmprc == 0) CIFSSMBClose(xid, tcon, fid.netfid); } diff --git a/fs/smb/client/smb2inode.c b/fs/smb/client/smb2inode.c index 8e696fbd72fa..260b2ed23cbd 100644 --- a/fs/smb/client/smb2inode.c +++ b/fs/smb/client/smb2inode.c @@ -541,9 +541,11 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, return rc; } -int smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, - struct cifs_sb_info *cifs_sb, const char *full_path, - struct cifs_open_info_data *data, bool *adjust_tz, bool *reparse) +int smb2_query_path_info(const unsigned int xid, + struct cifs_tcon *tcon, + struct cifs_sb_info *cifs_sb, + const char *full_path, + struct cifs_open_info_data *data) { __u32 create_options = 0; struct cifsFileInfo *cfile; @@ -553,8 +555,8 @@ int smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, bool islink; int rc, rc2; - *adjust_tz = false; - *reparse = false; + data->adjust_tz = false; + data->reparse_point = false; if (strcmp(full_path, "")) rc = -ENOENT; @@ -588,7 +590,7 @@ int smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, if (rc) goto out; - *reparse = true; + data->reparse_point = true; create_options |= OPEN_REPARSE_POINT; /* Failed on a symbolic link - query a reparse point info */ @@ -619,12 +621,13 @@ int smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, } -int smb311_posix_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, - struct cifs_sb_info *cifs_sb, const char *full_path, +int smb311_posix_query_path_info(const unsigned int xid, + struct cifs_tcon *tcon, + struct cifs_sb_info *cifs_sb, + const char *full_path, struct cifs_open_info_data *data, struct cifs_sid *owner, - struct cifs_sid *group, - bool *adjust_tz, bool *reparse) + struct cifs_sid *group) { int rc; __u32 create_options = 0; @@ -636,8 +639,8 @@ int smb311_posix_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, size_t sidsbuflen = 0; size_t owner_len, group_len; - *adjust_tz = false; - *reparse = false; + data->adjust_tz = false; + data->reparse_point = false; /* * BB TODO: Add support for using the cached root handle. @@ -659,7 +662,7 @@ int smb311_posix_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, if (rc) goto out; } - *reparse = true; + data->reparse_point = true; create_options |= OPEN_REPARSE_POINT; /* Failed on a symbolic link - query a reparse point info */ diff --git a/fs/smb/client/smb2proto.h b/fs/smb/client/smb2proto.h index d5d7ffb7711c..46eff9ec302a 100644 --- a/fs/smb/client/smb2proto.h +++ b/fs/smb/client/smb2proto.h @@ -56,9 +56,11 @@ extern int smb3_handle_read_data(struct TCP_Server_Info *server, extern int smb2_query_reparse_tag(const unsigned int xid, struct cifs_tcon *tcon, struct cifs_sb_info *cifs_sb, const char *path, __u32 *reparse_tag); -int smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, - struct cifs_sb_info *cifs_sb, const char *full_path, - struct cifs_open_info_data *data, bool *adjust_tz, bool *reparse); +int smb2_query_path_info(const unsigned int xid, + struct cifs_tcon *tcon, + struct cifs_sb_info *cifs_sb, + const char *full_path, + struct cifs_open_info_data *data); extern int smb2_set_path_size(const unsigned int xid, struct cifs_tcon *tcon, const char *full_path, __u64 size, struct cifs_sb_info *cifs_sb, bool set_alloc); @@ -275,12 +277,13 @@ extern int smb2_query_info_compound(const unsigned int xid, struct kvec *rsp, int *buftype, struct cifs_sb_info *cifs_sb); /* query path info from the server using SMB311 POSIX extensions*/ -int smb311_posix_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, - struct cifs_sb_info *cifs_sb, const char *full_path, +int smb311_posix_query_path_info(const unsigned int xid, + struct cifs_tcon *tcon, + struct cifs_sb_info *cifs_sb, + const char *full_path, struct cifs_open_info_data *data, struct cifs_sid *owner, - struct cifs_sid *group, - bool *adjust_tz, bool *reparse); + struct cifs_sid *group); int posix_info_parse(const void *beg, const void *end, struct smb2_posix_info_parsed *out); int posix_info_sid_size(const void *beg, const void *end); From patchwork Thu Aug 17 15:34:02 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paulo Alcantara X-Patchwork-Id: 13356724 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 C6FB9C3DA42 for ; Thu, 17 Aug 2023 15:36:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1352677AbjHQPfo (ORCPT ); Thu, 17 Aug 2023 11:35:44 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42676 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1353243AbjHQPfe (ORCPT ); Thu, 17 Aug 2023 11:35:34 -0400 Received: from mx.manguebit.com (mx.manguebit.com [IPv6:2a01:4f8:1c1e:a2ae::2]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8D3B52D6D for ; Thu, 17 Aug 2023 08:35:32 -0700 (PDT) From: Paulo Alcantara DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=manguebit.com; s=dkim; t=1692286531; 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=LrZMOK4/QrgBa6EaAvtHiDfPReQxxc2saqf8lIctoRQ=; b=WaQa/eX22X4WoxlKvzaaWNYEpOaeYJBbs4rqz/BBp73sCijd3v/JfHdhdGfoPBaerjR0xF FWTgNa7nfJs4CjMZTOnHnwPjVVvzzx+vnxYPw5wCgD4uyQXbaJL7xo9UO/IDv6e5Wjt4T7 HX4HzNn9ZBrQCETv+negQj45jSv63L7HbHQ9fSvJsXBuFdJXVkjDvAN7von4fh/f8HgIdK kvvrCiC1O6G9G75kDaMhWPMCdLRQWJyBCJkhQFncgDqu6wvTsmdqY0PuMDfy7Ol4TPv4QC NZa+9Lf4VN72fEytAgc5lb4LiL3urabFLaNj/kq1l3Pp9VSLp3afositY7BUbg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=manguebit.com; s=dkim; t=1692286531; 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=LrZMOK4/QrgBa6EaAvtHiDfPReQxxc2saqf8lIctoRQ=; b=ay99Dx0f0E70ohe0MT+MD9OOtiaDR+YHYttD4pH5a09raDgChfyZtEsfIgdfZ8xebCY/1r MqIuTB3SQkgmWHWThzccluvHy9+QqVBa0kq4y4pfrDaAGeNxIUNjO7zPfIkX1jBljFhSko qvwWHoRqF4v8gMz1MtVJNQcrq4eaSZrzwmgLTkvnXNi+vCHp8iKqIl9Wa5j2jtgWWM8WM8 dS5cGFntiyjXiZs9RqBxTiVlAzyDZMFQR38svvmHNdnQsyal5i1eL7l6VLQc46BToItOfc gXmv2cgmTnxKM/JC7qHzAljUbCV1i5jsjb8aFb1gMC8tcuqo360gXGI7OwCyyg== ARC-Authentication-Results: i=1; ORIGINATING; auth=pass smtp.auth=pc@manguebit.com smtp.mailfrom=pc@manguebit.com ARC-Seal: i=1; s=dkim; d=manguebit.com; t=1692286531; a=rsa-sha256; cv=none; b=DSEbZOALuzZtblLkauLXxx1NtdTGTLoQdZtdlpBPp+1WJNhvWEz4TFi1LiHJCYLSaDUiJP jmCbfbt+4ZwxGaLJyGIOkMuh+mhNo902CDJzjxilqfjqMxCAfbLtXqSYCQ5kbkxHMigQsp nsr11oy5veK7XQXSxZ9pmcH1r7a3hqXDzhm8fPmxvDRQqxscIj1c8EwCCUGAAHt/wBF9gu GKlPEL62YcmXi4ll4Ufkk3Zd4ciWszngUsrKBl/26/NXWYaFTebr7S+sTGP1Kqr70203F9 uAiFBzN629ZtsDJlAzzXWxthtwfkLMyjvhpMN7TpR3FsI4KiIY1RsYL0r5Pepw== To: smfrench@gmail.com Cc: linux-cifs@vger.kernel.org, Paulo Alcantara Subject: [PATCH 04/17] smb: client: make smb2_compound_op() return resp buffer on success Date: Thu, 17 Aug 2023 12:34:02 -0300 Message-ID: <20230817153416.28083-5-pc@manguebit.com> In-Reply-To: <20230817153416.28083-1-pc@manguebit.com> References: <20230817153416.28083-1-pc@manguebit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org If @out_iov and @out_buftype are passed, then return compounded responses regardless whether the request failed or not. This will be useful for detecting reparse points on SMB2_CREATE responses as specified in MS-SMB2 2.2.14. No functional changes. Signed-off-by: Paulo Alcantara (SUSE) --- fs/smb/client/smb2inode.c | 52 +++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/fs/smb/client/smb2inode.c b/fs/smb/client/smb2inode.c index 260b2ed23cbd..69a2969ecdf5 100644 --- a/fs/smb/client/smb2inode.c +++ b/fs/smb/client/smb2inode.c @@ -52,15 +52,16 @@ struct cop_vars { * note: If cfile is passed, the reference to it is dropped here. * So make sure that you do not reuse cfile after return from this func. * - * If passing @err_iov and @err_buftype, ensure to make them both large enough (>= 3) to hold all - * error responses. Caller is also responsible for freeing them up. + * If passing @out_iov and @out_buftype, ensure to make them both large enough + * (>= 3) to hold all compounded responses. Caller is also responsible for + * freeing them up with free_rsp_buf(). */ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, struct cifs_sb_info *cifs_sb, const char *full_path, __u32 desired_access, __u32 create_disposition, __u32 create_options, umode_t mode, void *ptr, int command, struct cifsFileInfo *cfile, __u8 **extbuf, size_t *extbuflen, - struct kvec *err_iov, int *err_buftype) + struct kvec *out_iov, int *out_buftype) { struct cop_vars *vars = NULL; struct kvec *rsp_iov; @@ -529,9 +530,9 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, if (cfile) cifsFileInfo_put(cfile); - if (rc && err_iov && err_buftype) { - memcpy(err_iov, rsp_iov, 3 * sizeof(*err_iov)); - memcpy(err_buftype, resp_buftype, 3 * sizeof(*err_buftype)); + if (out_iov && out_buftype) { + memcpy(out_iov, rsp_iov, 3 * sizeof(*out_iov)); + memcpy(out_buftype, resp_buftype, 3 * sizeof(*out_buftype)); } else { free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base); free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base); @@ -550,8 +551,8 @@ int smb2_query_path_info(const unsigned int xid, __u32 create_options = 0; struct cifsFileInfo *cfile; struct cached_fid *cfid = NULL; - struct kvec err_iov[3] = {}; - int err_buftype[3] = {}; + struct kvec out_iov[3] = {}; + int out_buftype[3] = {}; bool islink; int rc, rc2; @@ -577,15 +578,15 @@ int smb2_query_path_info(const unsigned int xid, cifs_get_readable_path(tcon, full_path, &cfile); rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, FILE_READ_ATTRIBUTES, FILE_OPEN, create_options, ACL_NO_MODE, data, SMB2_OP_QUERY_INFO, cfile, - NULL, NULL, err_iov, err_buftype); + NULL, NULL, out_iov, out_buftype); if (rc) { - struct smb2_hdr *hdr = err_iov[0].iov_base; + struct smb2_hdr *hdr = out_iov[0].iov_base; - if (unlikely(!hdr || err_buftype[0] == CIFS_NO_BUFFER)) + if (unlikely(!hdr || out_buftype[0] == CIFS_NO_BUFFER)) goto out; if (rc == -EOPNOTSUPP && hdr->Command == SMB2_CREATE && hdr->Status == STATUS_STOPPED_ON_SYMLINK) { - rc = smb2_parse_symlink_response(cifs_sb, err_iov, + rc = smb2_parse_symlink_response(cifs_sb, out_iov, &data->symlink_target); if (rc) goto out; @@ -614,13 +615,12 @@ int smb2_query_path_info(const unsigned int xid, } out: - free_rsp_buf(err_buftype[0], err_iov[0].iov_base); - free_rsp_buf(err_buftype[1], err_iov[1].iov_base); - free_rsp_buf(err_buftype[2], err_iov[2].iov_base); + free_rsp_buf(out_buftype[0], out_iov[0].iov_base); + free_rsp_buf(out_buftype[1], out_iov[1].iov_base); + free_rsp_buf(out_buftype[2], out_iov[2].iov_base); return rc; } - int smb311_posix_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, struct cifs_sb_info *cifs_sb, @@ -632,8 +632,8 @@ int smb311_posix_query_path_info(const unsigned int xid, int rc; __u32 create_options = 0; struct cifsFileInfo *cfile; - struct kvec err_iov[3] = {}; - int err_buftype[3] = {}; + struct kvec out_iov[3] = {}; + int out_buftype[3] = {}; __u8 *sidsbuf = NULL; __u8 *sidsbuf_end = NULL; size_t sidsbuflen = 0; @@ -652,13 +652,13 @@ int smb311_posix_query_path_info(const unsigned int xid, cifs_get_readable_path(tcon, full_path, &cfile); rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, FILE_READ_ATTRIBUTES, FILE_OPEN, create_options, ACL_NO_MODE, data, SMB2_OP_POSIX_QUERY_INFO, cfile, - &sidsbuf, &sidsbuflen, err_iov, err_buftype); + &sidsbuf, &sidsbuflen, out_iov, out_buftype); if (rc == -EOPNOTSUPP) { /* BB TODO: When support for special files added to Samba re-verify this path */ - if (err_iov[0].iov_base && err_buftype[0] != CIFS_NO_BUFFER && - ((struct smb2_hdr *)err_iov[0].iov_base)->Command == SMB2_CREATE && - ((struct smb2_hdr *)err_iov[0].iov_base)->Status == STATUS_STOPPED_ON_SYMLINK) { - rc = smb2_parse_symlink_response(cifs_sb, err_iov, &data->symlink_target); + if (out_iov[0].iov_base && out_buftype[0] != CIFS_NO_BUFFER && + ((struct smb2_hdr *)out_iov[0].iov_base)->Command == SMB2_CREATE && + ((struct smb2_hdr *)out_iov[0].iov_base)->Status == STATUS_STOPPED_ON_SYMLINK) { + rc = smb2_parse_symlink_response(cifs_sb, out_iov, &data->symlink_target); if (rc) goto out; } @@ -694,9 +694,9 @@ int smb311_posix_query_path_info(const unsigned int xid, out: kfree(sidsbuf); - free_rsp_buf(err_buftype[0], err_iov[0].iov_base); - free_rsp_buf(err_buftype[1], err_iov[1].iov_base); - free_rsp_buf(err_buftype[2], err_iov[2].iov_base); + free_rsp_buf(out_buftype[0], out_iov[0].iov_base); + free_rsp_buf(out_buftype[1], out_iov[1].iov_base); + free_rsp_buf(out_buftype[2], out_iov[2].iov_base); return rc; } From patchwork Thu Aug 17 15:34:03 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paulo Alcantara X-Patchwork-Id: 13356718 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 45AC6C3065C for ; Thu, 17 Aug 2023 15:36:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1352655AbjHQPfn (ORCPT ); Thu, 17 Aug 2023 11:35:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42696 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1353245AbjHQPff (ORCPT ); Thu, 17 Aug 2023 11:35:35 -0400 Received: from mx.manguebit.com (mx.manguebit.com [167.235.159.17]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4685E30C6 for ; Thu, 17 Aug 2023 08:35:34 -0700 (PDT) From: Paulo Alcantara DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=manguebit.com; s=dkim; t=1692286532; 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=b4G8IX/C+szWZEC+eyjEy6RY7fSFjat6ysiasaBDFw0=; b=YulqEpCILganxHpw/yjtIbB4LF0vMhXc465dhc9ZvZ+Ut3p5jRfmDW8UUInt4/xlzdw6H4 hjzeZ3fNGL7DaPuIlHDCWtxBd1rMJ5B9zLARfsaVHCVOZUj+tEYrSuT57M0mc3uSHVRaV/ c1ndsW48yuAvQeyHF8+pdgfuJExboaaZc5HELpEssCNjqclQj+d/EUgIHXeomxnxxpXbpq +GBOEDNh1NsmX+CSpcAUw2PupQthtYVPO/r3sFTKx5FF192Qt7HCyhcGW2TPOeUz67YFSh tu24PFKaNC+mcu7kU4QON8WcnAbCDITVKvTufuKhbFFWj+oHnPuifCMKYlO1Yg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=manguebit.com; s=dkim; t=1692286532; 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=b4G8IX/C+szWZEC+eyjEy6RY7fSFjat6ysiasaBDFw0=; b=ByyJRoTvRWtkZce4qO5eSOsl1iC7ziWbW8sy+tEeLFi/a82OtpX4ZOMRSq7rwNB4XBy49m Un+HuStEBbX5A5t3QHwaVxP56mwzo6OyTlhvUx1X/kBPQFxhaGeUmwJg1DqhbJl/5HYFWy 7sO7oiLQ1j/5qEVLSe8LTkgbo+AjcPJzJkWpOYTZpJHCP28IA0wyz4/tPCYo+M7Nq7I84q 5mPZ3GZ6RPQY4CYjbg/v6udzZh5DKobpbHmX1/N84L11eYZAog6j2ASOBUmhaWg/yhHs5c 1eJhJibzkAFUmkBKC/bTdZ78GN9+B+BVT65lHnXysDNwEZMy8LSzbNR6oJrmXA== ARC-Authentication-Results: i=1; ORIGINATING; auth=pass smtp.auth=pc@manguebit.com smtp.mailfrom=pc@manguebit.com ARC-Seal: i=1; s=dkim; d=manguebit.com; t=1692286532; a=rsa-sha256; cv=none; b=qMWZnqr7UpXOCmXRHsFJCU8TbSBXsB9iBBD7AG+fIKNGx1EQspv0xOWhQ8AsMV4K9KoQgf fFheIrr+5zjaaE2LLWA98lGqN5tSezgAmeuzYUIpp1ccIT2GLHl8aA/SYuEr884lzA3pdL BeWE72xaHMvTb+LCBcY8BA5rAACd/5SaW8K32UUj5ZWLeeP7X6dlc3m9vWHRCUclPTZR3D ln6GKaxaD0GgQcUDzPasZWu4qJTBN9jOMQGrEEP/ml54dFmwoRa6AjCpucltkWCpMwE+2Z 2Qoejmoz0OF+6Zmj6yoe6ZRQZqRk356J3dpYGOrW5SfY6ARPqNgyxRKQp8EtjA== To: smfrench@gmail.com Cc: linux-cifs@vger.kernel.org, Paulo Alcantara Subject: [PATCH 05/17] smb: client: rename cifs_dfs_ref.c to namespace.c Date: Thu, 17 Aug 2023 12:34:03 -0300 Message-ID: <20230817153416.28083-6-pc@manguebit.com> In-Reply-To: <20230817153416.28083-1-pc@manguebit.com> References: <20230817153416.28083-1-pc@manguebit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org The automount code will handle both DFS links and reparse files that are mount points. Signed-off-by: Paulo Alcantara (SUSE) --- fs/smb/client/Makefile | 2 +- fs/smb/client/{cifs_dfs_ref.c => namespace.c} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename fs/smb/client/{cifs_dfs_ref.c => namespace.c} (100%) diff --git a/fs/smb/client/Makefile b/fs/smb/client/Makefile index 304a7f6cc13a..851e6ba65e9b 100644 --- a/fs/smb/client/Makefile +++ b/fs/smb/client/Makefile @@ -21,7 +21,7 @@ cifs-$(CONFIG_CIFS_XATTR) += xattr.o cifs-$(CONFIG_CIFS_UPCALL) += cifs_spnego.o -cifs-$(CONFIG_CIFS_DFS_UPCALL) += cifs_dfs_ref.o dfs_cache.o dfs.o +cifs-$(CONFIG_CIFS_DFS_UPCALL) += namespace.o dfs_cache.o dfs.o cifs-$(CONFIG_CIFS_SWN_UPCALL) += netlink.o cifs_swn.o diff --git a/fs/smb/client/cifs_dfs_ref.c b/fs/smb/client/namespace.c similarity index 100% rename from fs/smb/client/cifs_dfs_ref.c rename to fs/smb/client/namespace.c From patchwork Thu Aug 17 15:34:04 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paulo Alcantara X-Patchwork-Id: 13356725 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 9FC36C3DA40 for ; Thu, 17 Aug 2023 15:36:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1352757AbjHQPfp (ORCPT ); Thu, 17 Aug 2023 11:35:45 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42712 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1353246AbjHQPfh (ORCPT ); Thu, 17 Aug 2023 11:35:37 -0400 Received: from mx.manguebit.com (mx.manguebit.com [167.235.159.17]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B457430C6 for ; Thu, 17 Aug 2023 08:35:35 -0700 (PDT) From: Paulo Alcantara DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=manguebit.com; s=dkim; t=1692286534; 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=J+qC7fw5PBrM2g10SnT+3E6TH4omTAkAHDXNRo187g8=; b=SLRoYipqRGV0JrcJQmBip9h6A6bdy/bX4YpiUIDStyFdwzwAqT+8pkN9o9hRMCK/Ji7nA3 qJ3uDgtbBvnjgKWmYGO5/jkEUH/FDjg6DjtSUj73+KdLNF0RXyOiUpsq/e+fOwu0xbwnxr 6Yh3Ss/VFssIntlP84+blNnLzdiZ42QN8KSlpGbH608fahceOySo95RAJi2/66nl+jcAzp XtA6HqqQLti3wM2E1H0/U8hZDmnsCFZImKS4oBdcyA+oISsvS4Gf3FidXFicffot+MB76T P5DpmEQQsd1Lly/Hvl61CFBgt+Ffpn+y4lJ37qoFHoZHymewhZImLiXczFwBIQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=manguebit.com; s=dkim; t=1692286534; 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=J+qC7fw5PBrM2g10SnT+3E6TH4omTAkAHDXNRo187g8=; b=WNI074jkOFzfuGRMsXaPygsMfXgGprIWSYOcO71WQIweKmRPK0rZ80CrEkszgs0V+LZNFJ DSXg8E82tcvJ59FrOAit9FXva6D5qVwRP3hdJelEnmWjdGDuBiCgemFsOoftBfPrJqLjUc +x52AIWQvlN8sX/FHRzonBxlISox/+BiB0baK6XFCYdkWttKqCnUDV1YPNtrG/yaaZSzzQ a96jrfDWbJeue7oa83C/QWLxrVJ72GSaUnKPwcOpLLJpMmJMKCy0RwkPaO6jJ4HACsFG7D YtNnR1hCuzDWMpVizotCHNS1jUQrJup7DPOYFr5BsBDnOCpmb7UgQDDC1LrmSg== ARC-Authentication-Results: i=1; ORIGINATING; auth=pass smtp.auth=pc@manguebit.com smtp.mailfrom=pc@manguebit.com ARC-Seal: i=1; s=dkim; d=manguebit.com; t=1692286534; a=rsa-sha256; cv=none; b=Dv5O6ZdWISIbfzXre71VcISd6TwQFG70aJlpmCKbHSkPwMqXHz0jWK8mXam6mvtvcvxoYG HGrk3YYfbXhqgsrS0lPtdDOmIs46GnFaeQ6h3nivGEhV1ZM8uaVg7xCvIrTyP6Map8Gzfq bjpjYdhNhHex75EjobjWfczqlu1ty3R2k/K15W1rto2+FoIy3DBnbmT5loq33CqXJVRAWg vl8EzYek9yt7UiFuBDBWiSjxHrGnJaNeFr+84nCNNQq8mK8dbiq7o9Zr2THVDdeJhiqKGo 1zjW5/cD2ZcVgOzWHWM/SlbhXjKuUH/hGpYqA2+HPP+Rf3iKLxCorObJFgzq2Q== To: smfrench@gmail.com Cc: linux-cifs@vger.kernel.org, Paulo Alcantara Subject: [PATCH 06/17] smb: client: get rid of dfs naming in automount code Date: Thu, 17 Aug 2023 12:34:04 -0300 Message-ID: <20230817153416.28083-7-pc@manguebit.com> In-Reply-To: <20230817153416.28083-1-pc@manguebit.com> References: <20230817153416.28083-1-pc@manguebit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Automount code will handle both DFS links and reparse mount points. Also, get rid of BUG_ON() in cifs_release_automount_timer() while we're at it. Signed-off-by: Paulo Alcantara (SUSE) --- fs/smb/client/cifsfs.c | 2 +- fs/smb/client/cifsfs.h | 6 +++--- fs/smb/client/cifsproto.h | 4 ++-- fs/smb/client/dir.c | 4 ++-- fs/smb/client/inode.c | 2 +- fs/smb/client/namespace.c | 42 +++++++++++++++++++-------------------- 6 files changed, 30 insertions(+), 30 deletions(-) diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c index a4d8b0ea1c8c..d49fd2bf71b0 100644 --- a/fs/smb/client/cifsfs.c +++ b/fs/smb/client/cifsfs.c @@ -1805,7 +1805,7 @@ exit_cifs(void) cifs_dbg(NOISY, "exit_smb3\n"); unregister_filesystem(&cifs_fs_type); unregister_filesystem(&smb3_fs_type); - cifs_dfs_release_automount_timer(); + cifs_release_automount_timer(); exit_cifs_idmap(); #ifdef CONFIG_CIFS_SWN_UPCALL cifs_genl_exit(); diff --git a/fs/smb/client/cifsfs.h b/fs/smb/client/cifsfs.h index 15c8cc4b6680..99075970716e 100644 --- a/fs/smb/client/cifsfs.h +++ b/fs/smb/client/cifsfs.h @@ -81,7 +81,7 @@ extern int cifs_fiemap(struct inode *, struct fiemap_extent_info *, u64 start, extern const struct inode_operations cifs_file_inode_ops; extern const struct inode_operations cifs_symlink_inode_ops; -extern const struct inode_operations cifs_dfs_referral_inode_operations; +extern const struct inode_operations cifs_namespace_inode_operations; /* Functions related to files and directories */ @@ -119,9 +119,9 @@ extern const struct dentry_operations cifs_dentry_ops; extern const struct dentry_operations cifs_ci_dentry_ops; #ifdef CONFIG_CIFS_DFS_UPCALL -extern struct vfsmount *cifs_dfs_d_automount(struct path *path); +extern struct vfsmount *cifs_d_automount(struct path *path); #else -static inline struct vfsmount *cifs_dfs_d_automount(struct path *path) +static inline struct vfsmount *cifs_d_automount(struct path *path) { return ERR_PTR(-EREMOTE); } diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h index 1d71d658e167..c7a7484efbd2 100644 --- a/fs/smb/client/cifsproto.h +++ b/fs/smb/client/cifsproto.h @@ -296,9 +296,9 @@ extern void cifs_put_tcp_session(struct TCP_Server_Info *server, extern void cifs_put_tcon(struct cifs_tcon *tcon); #if IS_ENABLED(CONFIG_CIFS_DFS_UPCALL) -extern void cifs_dfs_release_automount_timer(void); +extern void cifs_release_automount_timer(void); #else /* ! IS_ENABLED(CONFIG_CIFS_DFS_UPCALL) */ -#define cifs_dfs_release_automount_timer() do { } while (0) +#define cifs_release_automount_timer() do { } while (0) #endif /* ! IS_ENABLED(CONFIG_CIFS_DFS_UPCALL) */ void cifs_proc_init(void); diff --git a/fs/smb/client/dir.c b/fs/smb/client/dir.c index 30b1e1bfd204..580a27a3a7e6 100644 --- a/fs/smb/client/dir.c +++ b/fs/smb/client/dir.c @@ -797,7 +797,7 @@ cifs_d_revalidate(struct dentry *direntry, unsigned int flags) const struct dentry_operations cifs_dentry_ops = { .d_revalidate = cifs_d_revalidate, - .d_automount = cifs_dfs_d_automount, + .d_automount = cifs_d_automount, /* d_delete: cifs_d_delete, */ /* not needed except for debugging */ }; @@ -872,5 +872,5 @@ const struct dentry_operations cifs_ci_dentry_ops = { .d_revalidate = cifs_d_revalidate, .d_hash = cifs_ci_hash, .d_compare = cifs_ci_compare, - .d_automount = cifs_dfs_d_automount, + .d_automount = cifs_d_automount, }; diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c index 0d11e63042e2..0d4a78561acc 100644 --- a/fs/smb/client/inode.c +++ b/fs/smb/client/inode.c @@ -60,7 +60,7 @@ static void cifs_set_ops(struct inode *inode) case S_IFDIR: #ifdef CONFIG_CIFS_DFS_UPCALL if (IS_AUTOMOUNT(inode)) { - inode->i_op = &cifs_dfs_referral_inode_operations; + inode->i_op = &cifs_namespace_inode_operations; } else { #else /* NO DFS support, treat as a directory */ { diff --git a/fs/smb/client/namespace.c b/fs/smb/client/namespace.c index b1c2499b1c3b..af64f2add873 100644 --- a/fs/smb/client/namespace.c +++ b/fs/smb/client/namespace.c @@ -1,7 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-or-later /* - * Contains the CIFS DFS referral mounting routines used for handling - * traversal via DFS junction point + * Contains mounting routines used for handling traversal via SMB junctions. * * Copyright (c) 2007 Igor Mammedov * Copyright (C) International Business Machines Corp., 2008 @@ -24,27 +23,28 @@ #include "dfs.h" #include "fs_context.h" -static LIST_HEAD(cifs_dfs_automount_list); +static LIST_HEAD(cifs_automount_list); -static void cifs_dfs_expire_automounts(struct work_struct *work); -static DECLARE_DELAYED_WORK(cifs_dfs_automount_task, - cifs_dfs_expire_automounts); -static int cifs_dfs_mountpoint_expiry_timeout = 500 * HZ; +static void cifs_expire_automounts(struct work_struct *work); +static DECLARE_DELAYED_WORK(cifs_automount_task, + cifs_expire_automounts); +static int cifs_mountpoint_expiry_timeout = 500 * HZ; -static void cifs_dfs_expire_automounts(struct work_struct *work) +static void cifs_expire_automounts(struct work_struct *work) { - struct list_head *list = &cifs_dfs_automount_list; + struct list_head *list = &cifs_automount_list; mark_mounts_for_expiry(list); if (!list_empty(list)) - schedule_delayed_work(&cifs_dfs_automount_task, - cifs_dfs_mountpoint_expiry_timeout); + schedule_delayed_work(&cifs_automount_task, + cifs_mountpoint_expiry_timeout); } -void cifs_dfs_release_automount_timer(void) +void cifs_release_automount_timer(void) { - BUG_ON(!list_empty(&cifs_dfs_automount_list)); - cancel_delayed_work_sync(&cifs_dfs_automount_task); + if (WARN_ON(!list_empty(&cifs_automount_list))) + return; + cancel_delayed_work_sync(&cifs_automount_task); } /** @@ -132,7 +132,7 @@ static int set_dest_addr(struct smb3_fs_context *ctx) /* * Create a vfsmount that we can automount */ -static struct vfsmount *cifs_dfs_do_automount(struct path *path) +static struct vfsmount *cifs_do_automount(struct path *path) { int rc; struct dentry *mntpt = path->dentry; @@ -214,25 +214,25 @@ static struct vfsmount *cifs_dfs_do_automount(struct path *path) /* * Attempt to automount the referral */ -struct vfsmount *cifs_dfs_d_automount(struct path *path) +struct vfsmount *cifs_d_automount(struct path *path) { struct vfsmount *newmnt; cifs_dbg(FYI, "%s: %pd\n", __func__, path->dentry); - newmnt = cifs_dfs_do_automount(path); + newmnt = cifs_do_automount(path); if (IS_ERR(newmnt)) { cifs_dbg(FYI, "leaving %s [automount failed]\n" , __func__); return newmnt; } mntget(newmnt); /* prevent immediate expiration */ - mnt_set_expiry(newmnt, &cifs_dfs_automount_list); - schedule_delayed_work(&cifs_dfs_automount_task, - cifs_dfs_mountpoint_expiry_timeout); + mnt_set_expiry(newmnt, &cifs_automount_list); + schedule_delayed_work(&cifs_automount_task, + cifs_mountpoint_expiry_timeout); cifs_dbg(FYI, "leaving %s [ok]\n" , __func__); return newmnt; } -const struct inode_operations cifs_dfs_referral_inode_operations = { +const struct inode_operations cifs_namespace_inode_operations = { }; From patchwork Thu Aug 17 15:34:05 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paulo Alcantara X-Patchwork-Id: 13356722 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 7F14AC3065D for ; Thu, 17 Aug 2023 15:36:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1352676AbjHQPfo (ORCPT ); Thu, 17 Aug 2023 11:35:44 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42734 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1353248AbjHQPfi (ORCPT ); Thu, 17 Aug 2023 11:35:38 -0400 Received: from mx.manguebit.com (mx.manguebit.com [167.235.159.17]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4DCC130C5 for ; Thu, 17 Aug 2023 08:35:37 -0700 (PDT) From: Paulo Alcantara DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=manguebit.com; s=dkim; t=1692286536; 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=tsioSQiZ417b8RqCL1VpmHMw8YPV2IvsZHhxTbozTFg=; b=JR1Bvzn0PB3VoEAGXFaF7DS+aRxAcaV7FuwWxENixqNgRD5F7mnAkhn5YTxtgJfm4bOTid uggFk9vo+g8cEW22A9Sl2hEJDfnfRBkCKl78CTxFJSsBw21N9t2SEzg/PGaRhej1wSFCeX 4L+Amy0Ww9e0pOcok8PDE+SxyKbBr7DS3fYR8azMpn3GLBf6k2LS+2coO4aO7tMDNP3mdR P2ieVe5lgLiePf7wfEq/YoL4KdJDyNRHZVHJAmvOJBFnDzha+3HcftUIWccqUOiz16g92C IMazTeOEMp7tzYZdMw+mKl1iMMUvCdvr1tFr7Rg2BOu6RApq9BMJj4eCaYmUsA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=manguebit.com; s=dkim; t=1692286536; 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=tsioSQiZ417b8RqCL1VpmHMw8YPV2IvsZHhxTbozTFg=; b=pEESAX/8xhGEnSRn1mTxfGLQ7MjOLeAPyAwf9YKjPgGct98sztegR62r8zFpX8H6PX/VB9 HfQkH/GlnOCXxubE3+QlUDx4zvB7rB9XSV/jM1Ak+18zKhF+z74pcGjg6KeyEo9lSslqFS yCd3ehgmYxQjciocfTi/O10z8XB8vjw3TLDS58YqlHwK0j7OFC97yY5WJKM1KK/6ZYaqZ2 nxYCvDOChVPWUmpckFwIce63kOJMH++N6AVQOJcsuPeR4UZhOY+2vEF1i8glnO/B9VN0vT KeGFLCpm+wiPGBwkwMr9U0vPEJ8sRBhwe4rp5lRtWwG26WSGYnXxLYiFiarrSQ== ARC-Authentication-Results: i=1; ORIGINATING; auth=pass smtp.auth=pc@manguebit.com smtp.mailfrom=pc@manguebit.com ARC-Seal: i=1; s=dkim; d=manguebit.com; t=1692286536; a=rsa-sha256; cv=none; b=rIH1EkQTYUVmWv3ARJcNE7sbcJ/FfmNeVqBWcmkNwskVDimTu0eEYzT2bW4SmXdlqmOSyO LgqMT3O7/tRiFknmgWzcgr0gYOyOLBruuFc6YvF6jNff8S1ymuSND47oRrk2yBnxvj6lu0 Drud4Jzmdq7OLse6s2fV1zQV3QyHUDX8/l6kWhNNTxtAW2lt79QV3Lhv5LPWi3RzEWgiC+ bIgBNEVgEbM4VS+KUq8yqvn6ELosVufe9byMhGMKG4ZIPINzPreSAzg8Kf0x81swSYlPsk 5XAB+lGZczPNQtstflTUBKByZN0Ar3AflIMF91obz7rES/NAxe4k/b1vuCN/sw== To: smfrench@gmail.com Cc: linux-cifs@vger.kernel.org, Paulo Alcantara Subject: [PATCH 07/17] smb: client: get rid of dfs code dep in namespace.c Date: Thu, 17 Aug 2023 12:34:05 -0300 Message-ID: <20230817153416.28083-8-pc@manguebit.com> In-Reply-To: <20230817153416.28083-1-pc@manguebit.com> References: <20230817153416.28083-1-pc@manguebit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Make namespace.c being built without requiring CONFIG_CIFS_DFS_UPCALL=y by moving set_dest_addr() to dfs.c and call it at the beginning of dfs_mount_share() so it can chase the DFS link starting from the correct server in @ctx->dstaddr. Signed-off-by: Paulo Alcantara (SUSE) --- fs/smb/client/Makefile | 5 ++-- fs/smb/client/cifsfs.h | 7 ----- fs/smb/client/cifsproto.h | 4 --- fs/smb/client/dfs.c | 16 +++++++++++ fs/smb/client/dfs.h | 37 -------------------------- fs/smb/client/inode.c | 4 --- fs/smb/client/namespace.c | 56 ++++++++++++++++++++++++++------------- 7 files changed, 57 insertions(+), 72 deletions(-) diff --git a/fs/smb/client/Makefile b/fs/smb/client/Makefile index 851e6ba65e9b..0b07eb94c93b 100644 --- a/fs/smb/client/Makefile +++ b/fs/smb/client/Makefile @@ -11,7 +11,8 @@ cifs-y := trace.o cifsfs.o cifs_debug.o connect.o dir.o file.o \ readdir.o ioctl.o sess.o export.o unc.o winucase.o \ smb2ops.o smb2maperror.o smb2transport.o \ smb2misc.o smb2pdu.o smb2inode.o smb2file.o cifsacl.o fs_context.o \ - dns_resolve.o cifs_spnego_negtokeninit.asn1.o asn1.o + dns_resolve.o cifs_spnego_negtokeninit.asn1.o asn1.o \ + namespace.o $(obj)/asn1.o: $(obj)/cifs_spnego_negtokeninit.asn1.h @@ -21,7 +22,7 @@ cifs-$(CONFIG_CIFS_XATTR) += xattr.o cifs-$(CONFIG_CIFS_UPCALL) += cifs_spnego.o -cifs-$(CONFIG_CIFS_DFS_UPCALL) += namespace.o dfs_cache.o dfs.o +cifs-$(CONFIG_CIFS_DFS_UPCALL) += dfs_cache.o dfs.o cifs-$(CONFIG_CIFS_SWN_UPCALL) += netlink.o cifs_swn.o diff --git a/fs/smb/client/cifsfs.h b/fs/smb/client/cifsfs.h index 99075970716e..532c38fe07cd 100644 --- a/fs/smb/client/cifsfs.h +++ b/fs/smb/client/cifsfs.h @@ -118,14 +118,7 @@ extern void cifs_pages_write_redirty(struct inode *inode, loff_t start, unsigned extern const struct dentry_operations cifs_dentry_ops; extern const struct dentry_operations cifs_ci_dentry_ops; -#ifdef CONFIG_CIFS_DFS_UPCALL extern struct vfsmount *cifs_d_automount(struct path *path); -#else -static inline struct vfsmount *cifs_d_automount(struct path *path) -{ - return ERR_PTR(-EREMOTE); -} -#endif /* Functions related to symlinks */ extern const char *cifs_get_link(struct dentry *, struct inode *, diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h index c7a7484efbd2..694d16acdf61 100644 --- a/fs/smb/client/cifsproto.h +++ b/fs/smb/client/cifsproto.h @@ -295,11 +295,7 @@ extern void cifs_put_tcp_session(struct TCP_Server_Info *server, int from_reconnect); extern void cifs_put_tcon(struct cifs_tcon *tcon); -#if IS_ENABLED(CONFIG_CIFS_DFS_UPCALL) extern void cifs_release_automount_timer(void); -#else /* ! IS_ENABLED(CONFIG_CIFS_DFS_UPCALL) */ -#define cifs_release_automount_timer() do { } while (0) -#endif /* ! IS_ENABLED(CONFIG_CIFS_DFS_UPCALL) */ void cifs_proc_init(void); void cifs_proc_clean(void); diff --git a/fs/smb/client/dfs.c b/fs/smb/client/dfs.c index 71ee74041884..81b84151450d 100644 --- a/fs/smb/client/dfs.c +++ b/fs/smb/client/dfs.c @@ -263,12 +263,28 @@ static int __dfs_mount_share(struct cifs_mount_ctx *mnt_ctx) return rc; } +/* Resolve UNC hostname in @ctx->source and set ip addr in @ctx->dstaddr */ +static int update_fs_context_dstaddr(struct smb3_fs_context *ctx) +{ + struct sockaddr *addr = (struct sockaddr *)&ctx->dstaddr; + int rc; + + rc = dns_resolve_server_name_to_ip(ctx->source, addr, NULL); + if (!rc) + cifs_set_port(addr, ctx->port); + return rc; +} + int dfs_mount_share(struct cifs_mount_ctx *mnt_ctx, bool *isdfs) { struct smb3_fs_context *ctx = mnt_ctx->fs_ctx; bool nodfs = ctx->nodfs; int rc; + rc = update_fs_context_dstaddr(ctx); + if (rc) + return rc; + *isdfs = false; rc = get_session(mnt_ctx, NULL); if (rc) diff --git a/fs/smb/client/dfs.h b/fs/smb/client/dfs.h index c0a9eea6a2c5..875ab7ae57fc 100644 --- a/fs/smb/client/dfs.h +++ b/fs/smb/client/dfs.h @@ -138,43 +138,6 @@ static inline int dfs_get_referral(struct cifs_mount_ctx *mnt_ctx, const char *p cifs_remap(cifs_sb), path, ref, tl); } -/* Return DFS full path out of a dentry set for automount */ -static inline char *dfs_get_automount_devname(struct dentry *dentry, void *page) -{ - struct cifs_sb_info *cifs_sb = CIFS_SB(dentry->d_sb); - struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); - size_t len; - char *s; - - spin_lock(&tcon->tc_lock); - if (unlikely(!tcon->origin_fullpath)) { - spin_unlock(&tcon->tc_lock); - return ERR_PTR(-EREMOTE); - } - spin_unlock(&tcon->tc_lock); - - s = dentry_path_raw(dentry, page, PATH_MAX); - if (IS_ERR(s)) - return s; - /* for root, we want "" */ - if (!s[1]) - s++; - - spin_lock(&tcon->tc_lock); - len = strlen(tcon->origin_fullpath); - if (s < (char *)page + len) { - spin_unlock(&tcon->tc_lock); - return ERR_PTR(-ENAMETOOLONG); - } - - s -= len; - memcpy(s, tcon->origin_fullpath, len); - spin_unlock(&tcon->tc_lock); - convert_delimiter(s, '/'); - - return s; -} - static inline void dfs_put_root_smb_sessions(struct list_head *head) { struct dfs_root_ses *root, *tmp; diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c index 0d4a78561acc..da2ec48dc0f6 100644 --- a/fs/smb/client/inode.c +++ b/fs/smb/client/inode.c @@ -58,13 +58,9 @@ static void cifs_set_ops(struct inode *inode) inode->i_data.a_ops = &cifs_addr_ops; break; case S_IFDIR: -#ifdef CONFIG_CIFS_DFS_UPCALL if (IS_AUTOMOUNT(inode)) { inode->i_op = &cifs_namespace_inode_operations; } else { -#else /* NO DFS support, treat as a directory */ - { -#endif inode->i_op = &cifs_dir_inode_ops; inode->i_fop = &cifs_dir_ops; } diff --git a/fs/smb/client/namespace.c b/fs/smb/client/namespace.c index af64f2add873..3252fe33f7a3 100644 --- a/fs/smb/client/namespace.c +++ b/fs/smb/client/namespace.c @@ -6,6 +6,7 @@ * Copyright (C) International Business Machines Corp., 2008 * Author(s): Igor Mammedov (niallain@gmail.com) * Steve French (sfrench@us.ibm.com) + * Copyright (c) 2023 Paulo Alcantara */ #include @@ -18,9 +19,7 @@ #include "cifsglob.h" #include "cifsproto.h" #include "cifsfs.h" -#include "dns_resolve.h" #include "cifs_debug.h" -#include "dfs.h" #include "fs_context.h" static LIST_HEAD(cifs_automount_list); @@ -118,15 +117,41 @@ cifs_build_devname(char *nodename, const char *prepath) return dev; } -static int set_dest_addr(struct smb3_fs_context *ctx) +/* Return full path out of a dentry set for automount */ +static char *automount_fullpath(struct dentry *dentry, void *page) { - struct sockaddr *addr = (struct sockaddr *)&ctx->dstaddr; - int rc; + struct cifs_sb_info *cifs_sb = CIFS_SB(dentry->d_sb); + struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); + size_t len; + char *s; - rc = dns_resolve_server_name_to_ip(ctx->source, addr, NULL); - if (!rc) - cifs_set_port(addr, ctx->port); - return rc; + spin_lock(&tcon->tc_lock); + if (unlikely(!tcon->origin_fullpath)) { + spin_unlock(&tcon->tc_lock); + return ERR_PTR(-EREMOTE); + } + spin_unlock(&tcon->tc_lock); + + s = dentry_path_raw(dentry, page, PATH_MAX); + if (IS_ERR(s)) + return s; + /* for root, we want "" */ + if (!s[1]) + s++; + + spin_lock(&tcon->tc_lock); + len = strlen(tcon->origin_fullpath); + if (s < (char *)page + len) { + spin_unlock(&tcon->tc_lock); + return ERR_PTR(-ENAMETOOLONG); + } + + s -= len; + memcpy(s, tcon->origin_fullpath, len); + spin_unlock(&tcon->tc_lock); + convert_delimiter(s, '/'); + + return s; } /* @@ -166,7 +191,7 @@ static struct vfsmount *cifs_do_automount(struct path *path) ctx = smb3_fc2context(fc); page = alloc_dentry_path(); - full_path = dfs_get_automount_devname(mntpt, page); + full_path = automount_fullpath(mntpt, page); if (IS_ERR(full_path)) { mnt = ERR_CAST(full_path); goto out; @@ -196,15 +221,10 @@ static struct vfsmount *cifs_do_automount(struct path *path) ctx->source = NULL; goto out; } - cifs_dbg(FYI, "%s: ctx: source=%s UNC=%s prepath=%s dstaddr=%pISpc\n", - __func__, ctx->source, ctx->UNC, ctx->prepath, &ctx->dstaddr); - - rc = set_dest_addr(ctx); - if (!rc) - mnt = fc_mount(fc); - else - mnt = ERR_PTR(rc); + cifs_dbg(FYI, "%s: ctx: source=%s UNC=%s prepath=%s\n", + __func__, ctx->source, ctx->UNC, ctx->prepath); + mnt = fc_mount(fc); out: put_fs_context(fc); free_dentry_path(page); From patchwork Thu Aug 17 15:34:06 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paulo Alcantara X-Patchwork-Id: 13356723 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 8F670C3DA41 for ; Thu, 17 Aug 2023 15:36:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1352675AbjHQPfn (ORCPT ); Thu, 17 Aug 2023 11:35:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38896 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1353249AbjHQPfk (ORCPT ); Thu, 17 Aug 2023 11:35:40 -0400 Received: from mx.manguebit.com (mx.manguebit.com [167.235.159.17]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E40E930C5 for ; Thu, 17 Aug 2023 08:35:38 -0700 (PDT) From: Paulo Alcantara DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=manguebit.com; s=dkim; t=1692286537; 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=cb18Ulo8cWGi7nbOOAreRRYdVcAEMI5Zo5XtPXRkunA=; b=jV7zPS9IaB6y/yMt/sqheer0HJ+9DEO8Q/8HIbLzoMcx6YlprakkTMUuDrs+WKvcgWb21H W22KErRBulkn8FvVZujImHUoRQKlOdL76hkK4NIPiDLQyk3XY5bpyR0b6uuYc4bUdXkAWw vueGPOSx3QXcYzH+kIEAh/lmnAkw/fCmlCvcpxtRZo4XDJ/JsUUERRzT1h2R7jedh7bLXG 1G2XA1FB+IBzdOjhd1oO+rVMu8B6kfoTNaD0j6T9PEXKWDx8IDoDQc5ivjtc5gx5PlL+Xa UMmTBbeSKlb75rQU4KUIONuSpX6IKkHD+O1fcBSXrWvwkz6lbBy5SjgSZ0qujw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=manguebit.com; s=dkim; t=1692286537; 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=cb18Ulo8cWGi7nbOOAreRRYdVcAEMI5Zo5XtPXRkunA=; b=kQ3wPzyEBKpWpmcWEt6m6hXdv7jBSA0Sbe1pkQS3A8J7gvdFgUMaJr/q4i05vR/JCKJnPM jte9qpnWss8nFuk3erABY5QghMQk4g3VheLvFz483+JDCD1eK+lOhxBIOvJobGZwjrPS7N jl/7ET1vXsjMWOTjfbqWnRUdKYsHhpOgKfa+rhhFf07gCGvsDlBjD9TcHhKSzjFxLa9F74 tKQ8i1HK3lRydBzAWKQXuuipDFTlDxLZ6ZK6xJzvlXUBK14NXZ2+THmPMO1bFTkmN9m6aZ oWzwctrRnxD/WG2bmKk7co511VqwKL4+K8hg4weVjDtMQaIJ7/PmEHOpz5lxJw== ARC-Authentication-Results: i=1; ORIGINATING; auth=pass smtp.auth=pc@manguebit.com smtp.mailfrom=pc@manguebit.com ARC-Seal: i=1; s=dkim; d=manguebit.com; t=1692286537; a=rsa-sha256; cv=none; b=I6zg1knaZJA0PQamp7/vDikiu60zVlf+Tkv3pipeWQeT1S2BOgeYkFC+CW+S12ku02c9lU Kkh2E1p7UAwDzcc/iR4gMeMSSlvbkgcE/FEx0yMXDa1d2by6mDYdbKbW+gKLFPR0VikyKv 3E9nqCGWBRbwBJWaLJxmxtBefcROl/zk3OsLZkcMhtdDroJwutO2Ue6R19y6egJMnJw2sN sXevRg9C1yDwS3LXKW3aNBSkubejeuSCFipcg8GIa3UJNmtkId1uO4olAE0yQiENNvxLkA AA44KL3URax1vLz/xIupYY4oI6coi34auz3FoGvnYmyN7Z/wnaReDlV+LVeSrw== To: smfrench@gmail.com Cc: linux-cifs@vger.kernel.org, Paulo Alcantara Subject: [PATCH 08/17] smb: client: parse reparse point flag in create response Date: Thu, 17 Aug 2023 12:34:06 -0300 Message-ID: <20230817153416.28083-9-pc@manguebit.com> In-Reply-To: <20230817153416.28083-1-pc@manguebit.com> References: <20230817153416.28083-1-pc@manguebit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Check for reparse point flag on query info calls as specified in MS-SMB2 2.2.14. Signed-off-by: Paulo Alcantara (SUSE) --- fs/smb/client/cifsglob.h | 4 ++ fs/smb/client/cifsproto.h | 3 + fs/smb/client/inode.c | 121 ++++++++++++++++++++++++++------------ fs/smb/client/readdir.c | 22 ++----- fs/smb/client/smb2inode.c | 115 ++++++++++++++++++++++++------------ 5 files changed, 172 insertions(+), 93 deletions(-) diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h index 4792de20a447..95e62502cb01 100644 --- a/fs/smb/client/cifsglob.h +++ b/fs/smb/client/cifsglob.h @@ -199,6 +199,10 @@ struct cifs_open_info_data { }; }; +#define cifs_open_data_reparse(d) \ + ((d)->reparse_point || \ + (le32_to_cpu((d)->fi.Attributes) & ATTR_REPARSE)) + static inline void cifs_free_open_info(struct cifs_open_info_data *data) { kfree(data->symlink_target); diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h index 694d16acdf61..7d8035846680 100644 --- a/fs/smb/client/cifsproto.h +++ b/fs/smb/client/cifsproto.h @@ -207,6 +207,9 @@ extern struct inode *cifs_iget(struct super_block *sb, int cifs_get_inode_info(struct inode **inode, const char *full_path, struct cifs_open_info_data *data, struct super_block *sb, int xid, const struct cifs_fid *fid); +bool cifs_reparse_point_to_fattr(struct cifs_sb_info *cifs_sb, + struct cifs_fattr *fattr, + u32 tag); extern int smb311_posix_get_inode_info(struct inode **pinode, const char *search_path, struct super_block *sb, unsigned int xid); extern int cifs_get_inode_info_unix(struct inode **pinode, diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c index da2ec48dc0f6..51e2916730cf 100644 --- a/fs/smb/client/inode.c +++ b/fs/smb/client/inode.c @@ -687,6 +687,43 @@ static void smb311_posix_info_to_fattr(struct cifs_fattr *fattr, fattr->cf_mode, fattr->cf_uniqueid, fattr->cf_nlink); } +bool cifs_reparse_point_to_fattr(struct cifs_sb_info *cifs_sb, + struct cifs_fattr *fattr, + u32 tag) +{ + switch (tag) { + case IO_REPARSE_TAG_LX_SYMLINK: + fattr->cf_mode |= S_IFLNK | cifs_sb->ctx->file_mode; + fattr->cf_dtype = DT_LNK; + break; + case IO_REPARSE_TAG_LX_FIFO: + fattr->cf_mode |= S_IFIFO | cifs_sb->ctx->file_mode; + fattr->cf_dtype = DT_FIFO; + break; + case IO_REPARSE_TAG_AF_UNIX: + fattr->cf_mode |= S_IFSOCK | cifs_sb->ctx->file_mode; + fattr->cf_dtype = DT_SOCK; + break; + case IO_REPARSE_TAG_LX_CHR: + fattr->cf_mode |= S_IFCHR | cifs_sb->ctx->file_mode; + fattr->cf_dtype = DT_CHR; + break; + case IO_REPARSE_TAG_LX_BLK: + fattr->cf_mode |= S_IFBLK | cifs_sb->ctx->file_mode; + fattr->cf_dtype = DT_BLK; + break; + case 0: /* SMB1 symlink */ + case IO_REPARSE_TAG_SYMLINK: + case IO_REPARSE_TAG_NFS: + fattr->cf_mode = S_IFLNK; + fattr->cf_dtype = DT_LNK; + break; + default: + return false; + } + return true; +} + static void cifs_open_info_to_fattr(struct cifs_fattr *fattr, struct cifs_open_info_data *data, struct super_block *sb) @@ -694,7 +731,6 @@ static void cifs_open_info_to_fattr(struct cifs_fattr *fattr, struct smb2_file_all_info *info = &data->fi; struct cifs_sb_info *cifs_sb = CIFS_SB(sb); struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); - u32 reparse_tag = data->reparse_tag; memset(fattr, 0, sizeof(*fattr)); fattr->cf_cifsattrs = le32_to_cpu(info->Attributes); @@ -717,28 +753,13 @@ static void cifs_open_info_to_fattr(struct cifs_fattr *fattr, fattr->cf_eof = le64_to_cpu(info->EndOfFile); fattr->cf_bytes = le64_to_cpu(info->AllocationSize); fattr->cf_createtime = le64_to_cpu(info->CreationTime); - fattr->cf_nlink = le32_to_cpu(info->NumberOfLinks); - if (reparse_tag == IO_REPARSE_TAG_LX_SYMLINK) { - fattr->cf_mode |= S_IFLNK | cifs_sb->ctx->file_mode; - fattr->cf_dtype = DT_LNK; - } else if (reparse_tag == IO_REPARSE_TAG_LX_FIFO) { - fattr->cf_mode |= S_IFIFO | cifs_sb->ctx->file_mode; - fattr->cf_dtype = DT_FIFO; - } else if (reparse_tag == IO_REPARSE_TAG_AF_UNIX) { - fattr->cf_mode |= S_IFSOCK | cifs_sb->ctx->file_mode; - fattr->cf_dtype = DT_SOCK; - } else if (reparse_tag == IO_REPARSE_TAG_LX_CHR) { - fattr->cf_mode |= S_IFCHR | cifs_sb->ctx->file_mode; - fattr->cf_dtype = DT_CHR; - } else if (reparse_tag == IO_REPARSE_TAG_LX_BLK) { - fattr->cf_mode |= S_IFBLK | cifs_sb->ctx->file_mode; - fattr->cf_dtype = DT_BLK; - } else if (data->symlink || reparse_tag == IO_REPARSE_TAG_SYMLINK || - reparse_tag == IO_REPARSE_TAG_NFS) { - fattr->cf_mode = S_IFLNK; - fattr->cf_dtype = DT_LNK; - } else if (fattr->cf_cifsattrs & ATTR_DIRECTORY) { + + if (cifs_open_data_reparse(data) && + cifs_reparse_point_to_fattr(cifs_sb, fattr, data->reparse_tag)) + goto out_reparse; + + if (fattr->cf_cifsattrs & ATTR_DIRECTORY) { fattr->cf_mode = S_IFDIR | cifs_sb->ctx->dir_mode; fattr->cf_dtype = DT_DIR; /* @@ -767,6 +788,7 @@ static void cifs_open_info_to_fattr(struct cifs_fattr *fattr, } } +out_reparse: if (S_ISLNK(fattr->cf_mode)) { fattr->cf_symlink_target = data->symlink_target; data->symlink_target = NULL; @@ -957,6 +979,40 @@ static inline bool is_inode_cache_good(struct inode *ino) return ino && CIFS_CACHE_READ(CIFS_I(ino)) && CIFS_I(ino)->time != 0; } +static int query_reparse(struct cifs_open_info_data *data, + struct super_block *sb, + const unsigned int xid, + struct cifs_tcon *tcon, + const char *full_path, + struct cifs_fattr *fattr) +{ + struct TCP_Server_Info *server = tcon->ses->server; + struct cifs_sb_info *cifs_sb = CIFS_SB(sb); + bool reparse_point = data->reparse_point; + u32 tag = data->reparse_tag; + int rc = 0; + + if (!tag && server->ops->query_reparse_tag) { + server->ops->query_reparse_tag(xid, tcon, cifs_sb, + full_path, &tag); + } + switch ((data->reparse_tag = tag)) { + case 0: /* SMB1 symlink */ + reparse_point = false; + fallthrough; + case IO_REPARSE_TAG_NFS: + case IO_REPARSE_TAG_SYMLINK: + if (!data->symlink_target && server->ops->query_symlink) { + rc = server->ops->query_symlink(xid, tcon, + cifs_sb, full_path, + &data->symlink_target, + reparse_point); + } + break; + } + return rc; +} + int cifs_get_inode_info(struct inode **inode, const char *full_path, struct cifs_open_info_data *data, struct super_block *sb, int xid, const struct cifs_fid *fid) @@ -1002,23 +1058,12 @@ int cifs_get_inode_info(struct inode **inode, const char *full_path, * since we have to check if its reparse tag matches a known * special file type e.g. symlink or fifo or char etc. */ - if (data->reparse_point && data->symlink_target) { - data->reparse_tag = IO_REPARSE_TAG_SYMLINK; - } else if ((le32_to_cpu(data->fi.Attributes) & ATTR_REPARSE) && - server->ops->query_reparse_tag) { - tmprc = server->ops->query_reparse_tag(xid, tcon, cifs_sb, full_path, - &data->reparse_tag); - cifs_dbg(FYI, "%s: query_reparse_tag: rc = %d\n", __func__, tmprc); - if (server->ops->query_symlink) { - tmprc = server->ops->query_symlink(xid, tcon, cifs_sb, - full_path, - &data->symlink_target, - data->reparse_point); - cifs_dbg(FYI, "%s: query_symlink: rc = %d\n", - __func__, tmprc); - } + if (cifs_open_data_reparse(data)) { + rc = query_reparse(data, sb, xid, tcon, + full_path, &fattr); } - cifs_open_info_to_fattr(&fattr, data, sb); + if (!rc) + cifs_open_info_to_fattr(&fattr, data, sb); break; case -EREMOTE: /* DFS link, no metadata available on this server */ diff --git a/fs/smb/client/readdir.c b/fs/smb/client/readdir.c index ef638086d734..59bf542d5211 100644 --- a/fs/smb/client/readdir.c +++ b/fs/smb/client/readdir.c @@ -163,29 +163,19 @@ cifs_fill_common_info(struct cifs_fattr *fattr, struct cifs_sb_info *cifs_sb) * TODO: go through all documented reparse tags to see if we can * reasonably map some of them to directories vs. files vs. symlinks */ + if ((fattr->cf_cifsattrs & ATTR_REPARSE) && + cifs_reparse_point_to_fattr(cifs_sb, fattr, fattr->cf_cifstag)) + goto out_reparse; + if (fattr->cf_cifsattrs & ATTR_DIRECTORY) { fattr->cf_mode = S_IFDIR | cifs_sb->ctx->dir_mode; fattr->cf_dtype = DT_DIR; - } else if (fattr->cf_cifstag == IO_REPARSE_TAG_LX_SYMLINK) { - fattr->cf_mode |= S_IFLNK | cifs_sb->ctx->file_mode; - fattr->cf_dtype = DT_LNK; - } else if (fattr->cf_cifstag == IO_REPARSE_TAG_LX_FIFO) { - fattr->cf_mode |= S_IFIFO | cifs_sb->ctx->file_mode; - fattr->cf_dtype = DT_FIFO; - } else if (fattr->cf_cifstag == IO_REPARSE_TAG_AF_UNIX) { - fattr->cf_mode |= S_IFSOCK | cifs_sb->ctx->file_mode; - fattr->cf_dtype = DT_SOCK; - } else if (fattr->cf_cifstag == IO_REPARSE_TAG_LX_CHR) { - fattr->cf_mode |= S_IFCHR | cifs_sb->ctx->file_mode; - fattr->cf_dtype = DT_CHR; - } else if (fattr->cf_cifstag == IO_REPARSE_TAG_LX_BLK) { - fattr->cf_mode |= S_IFBLK | cifs_sb->ctx->file_mode; - fattr->cf_dtype = DT_BLK; - } else { /* TODO: should we mark some other reparse points (like DFSR) as directories? */ + } else { fattr->cf_mode = S_IFREG | cifs_sb->ctx->file_mode; fattr->cf_dtype = DT_REG; } +out_reparse: /* * We need to revalidate it further to make a decision about whether it * is a symbolic link, DFS referral or a reparse point with a direct diff --git a/fs/smb/client/smb2inode.c b/fs/smb/client/smb2inode.c index 69a2969ecdf5..0999383c0284 100644 --- a/fs/smb/client/smb2inode.c +++ b/fs/smb/client/smb2inode.c @@ -542,6 +542,33 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, return rc; } +static int parse_create_response(struct cifs_open_info_data *data, + struct cifs_sb_info *cifs_sb, + const struct kvec *iov) +{ + struct smb2_create_rsp *rsp = iov->iov_base; + bool reparse_point = false; + u32 tag = 0; + int rc = 0; + + switch (rsp->hdr.Status) { + case STATUS_STOPPED_ON_SYMLINK: + rc = smb2_parse_symlink_response(cifs_sb, iov, + &data->symlink_target); + if (rc) + return rc; + tag = IO_REPARSE_TAG_SYMLINK; + reparse_point = true; + break; + case STATUS_SUCCESS: + reparse_point = !!(rsp->Flags & SMB2_CREATE_FLAG_REPARSEPOINT); + break; + } + data->reparse_point = reparse_point; + data->reparse_tag = tag; + return rc; +} + int smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, struct cifs_sb_info *cifs_sb, @@ -551,6 +578,7 @@ int smb2_query_path_info(const unsigned int xid, __u32 create_options = 0; struct cifsFileInfo *cfile; struct cached_fid *cfid = NULL; + struct smb2_hdr *hdr; struct kvec out_iov[3] = {}; int out_buftype[3] = {}; bool islink; @@ -579,39 +607,43 @@ int smb2_query_path_info(const unsigned int xid, rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, FILE_READ_ATTRIBUTES, FILE_OPEN, create_options, ACL_NO_MODE, data, SMB2_OP_QUERY_INFO, cfile, NULL, NULL, out_iov, out_buftype); - if (rc) { - struct smb2_hdr *hdr = out_iov[0].iov_base; + hdr = out_iov[0].iov_base; + /* + * If first iov is unset, then SMB session was dropped or we've got a + * cached open file (@cfile). + */ + if (!hdr || out_buftype[0] == CIFS_NO_BUFFER) + goto out; - if (unlikely(!hdr || out_buftype[0] == CIFS_NO_BUFFER)) + switch (rc) { + case 0: + case -EOPNOTSUPP: + rc = parse_create_response(data, cifs_sb, &out_iov[0]); + if (rc || !data->reparse_point) goto out; - if (rc == -EOPNOTSUPP && hdr->Command == SMB2_CREATE && - hdr->Status == STATUS_STOPPED_ON_SYMLINK) { - rc = smb2_parse_symlink_response(cifs_sb, out_iov, - &data->symlink_target); - if (rc) - goto out; - data->reparse_point = true; - create_options |= OPEN_REPARSE_POINT; - - /* Failed on a symbolic link - query a reparse point info */ - cifs_get_readable_path(tcon, full_path, &cfile); - rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, - FILE_READ_ATTRIBUTES, FILE_OPEN, - create_options, ACL_NO_MODE, data, - SMB2_OP_QUERY_INFO, cfile, NULL, NULL, - NULL, NULL); + create_options |= OPEN_REPARSE_POINT; + /* Failed on a symbolic link - query a reparse point info */ + cifs_get_readable_path(tcon, full_path, &cfile); + rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, + FILE_READ_ATTRIBUTES, FILE_OPEN, + create_options, ACL_NO_MODE, data, + SMB2_OP_QUERY_INFO, cfile, NULL, NULL, + NULL, NULL); + break; + case -EREMOTE: + break; + default: + if (hdr->Status != STATUS_OBJECT_NAME_INVALID) + break; + rc2 = cifs_inval_name_dfs_link_error(xid, tcon, cifs_sb, + full_path, &islink); + if (rc2) { + rc = rc2; goto out; - } else if (rc != -EREMOTE && hdr->Status == STATUS_OBJECT_NAME_INVALID) { - rc2 = cifs_inval_name_dfs_link_error(xid, tcon, cifs_sb, - full_path, &islink); - if (rc2) { - rc = rc2; - goto out; - } - if (islink) - rc = -EREMOTE; } + if (islink) + rc = -EREMOTE; } out: @@ -653,26 +685,32 @@ int smb311_posix_query_path_info(const unsigned int xid, rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, FILE_READ_ATTRIBUTES, FILE_OPEN, create_options, ACL_NO_MODE, data, SMB2_OP_POSIX_QUERY_INFO, cfile, &sidsbuf, &sidsbuflen, out_iov, out_buftype); - if (rc == -EOPNOTSUPP) { + /* + * If first iov is unset, then SMB session was dropped or we've got a + * cached open file (@cfile). + */ + if (!out_iov[0].iov_base || out_buftype[0] == CIFS_NO_BUFFER) + goto out; + + switch (rc) { + case 0: + case -EOPNOTSUPP: /* BB TODO: When support for special files added to Samba re-verify this path */ - if (out_iov[0].iov_base && out_buftype[0] != CIFS_NO_BUFFER && - ((struct smb2_hdr *)out_iov[0].iov_base)->Command == SMB2_CREATE && - ((struct smb2_hdr *)out_iov[0].iov_base)->Status == STATUS_STOPPED_ON_SYMLINK) { - rc = smb2_parse_symlink_response(cifs_sb, out_iov, &data->symlink_target); - if (rc) - goto out; - } - data->reparse_point = true; - create_options |= OPEN_REPARSE_POINT; + rc = parse_create_response(data, cifs_sb, &out_iov[0]); + if (rc || !data->reparse_point) + goto out; + create_options |= OPEN_REPARSE_POINT; /* Failed on a symbolic link - query a reparse point info */ cifs_get_readable_path(tcon, full_path, &cfile); rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, FILE_READ_ATTRIBUTES, FILE_OPEN, create_options, ACL_NO_MODE, data, SMB2_OP_POSIX_QUERY_INFO, cfile, &sidsbuf, &sidsbuflen, NULL, NULL); + break; } +out: if (rc == 0) { sidsbuf_end = sidsbuf + sidsbuflen; @@ -692,7 +730,6 @@ int smb311_posix_query_path_info(const unsigned int xid, memcpy(group, sidsbuf + owner_len, group_len); } -out: kfree(sidsbuf); free_rsp_buf(out_buftype[0], out_iov[0].iov_base); free_rsp_buf(out_buftype[1], out_iov[1].iov_base); From patchwork Thu Aug 17 15:34:07 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paulo Alcantara X-Patchwork-Id: 13356726 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 D6817C3065B for ; Thu, 17 Aug 2023 15:36:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1352319AbjHQPgO (ORCPT ); Thu, 17 Aug 2023 11:36:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38914 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1352648AbjHQPfm (ORCPT ); Thu, 17 Aug 2023 11:35:42 -0400 Received: from mx.manguebit.com (mx.manguebit.com [167.235.159.17]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 88A6430D1 for ; Thu, 17 Aug 2023 08:35:40 -0700 (PDT) From: Paulo Alcantara DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=manguebit.com; s=dkim; t=1692286539; 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=WpdE04ntbvSybELPr/OUl0HYBJZ4qbr7PZulNYTHk/g=; b=HzLUFc5k9vlBZgJnV5dxlu9RFP8ODME449k2b8cnZ3+W4cqov9eyeVLUpgTQIZi5fZq4YO Nkkx36SKNYW62y21NH0wvwwMe6V9BWD9AJ2IstfKgMlgj6u5mtazb4jW23xFqaQlgRIsN0 V72gkcAsUtKkJ5nW1OOpnZ2E5vcQRi6l8m0xL/wHZzdQrxSjGsyjctdFzPLSsoJFYHSaIo 0xMOkd897BeKpH88O+usUxsqdYL1VRZ7TkiYEAdbAn35I3Boq0ts6E3eoqbtVUYM0Xbl/9 WAqHtj4SIEgHQhAyNtApYw2r6nWmFLBgn6gHtRHy38T2DBPCNuLEXCE7c/xlvQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=manguebit.com; s=dkim; t=1692286539; 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=WpdE04ntbvSybELPr/OUl0HYBJZ4qbr7PZulNYTHk/g=; b=Jzznb7Su+vGa6sDVsM+1si/4DGsG3lZNC6sBycJa7a5SpuGpjkjXNOhGM9Ucb6C7mWs5yk Dxyi1sKT/rJt/lt4jt0QG2nJCuyVfqcmF+nKW4sKEYcqTpBsYM0n9d8YVBA5UoGMNMinN+ Qvdhm+nluVNXoJVUq0LRE8cIF8E5V+GR2ipzfhSGJ4FXTSiCrtX3yr4pFfgg46X90k0Hy8 h5aDMGOlA0MRDG5/MVW6VT7IqdolX+4co7UDyudvzDBZpx/iucvhRMgdO+2/5vDwbiRMkZ MS4wBis0CIoS6ybJXBJEmivkga7mUe19JwBmP46a6XVzCDmUPnFEfLegfmaE4g== ARC-Authentication-Results: i=1; ORIGINATING; auth=pass smtp.auth=pc@manguebit.com smtp.mailfrom=pc@manguebit.com ARC-Seal: i=1; s=dkim; d=manguebit.com; t=1692286539; a=rsa-sha256; cv=none; b=s8Gd+kSxjhT3K5KFUeAxWM4VrrNdh6rC3Wo5hrs4/CioM2ToU+pX64M/9onzC7ZpuWRCL7 uqC5l9GE18IHoPPBd7PoScPc7CJ8S+F+c6q7DZSdmobgyaUOZWF4tLFho6xc+MUhCmx3d4 p6GFoEmQV432W2hCztwMgkyABv3BgH14LXuYGfdZo2JMjUAuvsR8sUPiTzMkojYUyDpP2O N9dKRVIn1A6hCdNrXkm39+odRI1hqWmGoSH70ME3HZx/VlprTKKe+iJ+6yxCeU0LgsVYID ywKieRF7zn9i1TjRpNss0xKLA986uuot1MdhFjbwJ87+4TP2Zld5b+6+IIqttw== To: smfrench@gmail.com Cc: linux-cifs@vger.kernel.org, Paulo Alcantara Subject: [PATCH 09/17] smb: client: do not query reparse points twice on symlinks Date: Thu, 17 Aug 2023 12:34:07 -0300 Message-ID: <20230817153416.28083-10-pc@manguebit.com> In-Reply-To: <20230817153416.28083-1-pc@manguebit.com> References: <20230817153416.28083-1-pc@manguebit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Save a roundtrip by getting the reparse point tag and buffer at once in ->query_reparse_point() and then pass the buffer down to ->query_symlink(). Signed-off-by: Paulo Alcantara (SUSE) --- fs/smb/client/cifsglob.h | 20 +++-- fs/smb/client/inode.c | 19 +++-- fs/smb/client/smb1ops.c | 11 ++- fs/smb/client/smb2ops.c | 166 ++++++--------------------------------- 4 files changed, 55 insertions(+), 161 deletions(-) diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h index 95e62502cb01..639a61417b08 100644 --- a/fs/smb/client/cifsglob.h +++ b/fs/smb/client/cifsglob.h @@ -336,10 +336,13 @@ struct smb_version_operations { /* query file data from the server */ int (*query_file_info)(const unsigned int xid, struct cifs_tcon *tcon, struct cifsFileInfo *cfile, struct cifs_open_info_data *data); - /* query reparse tag from srv to determine which type of special file */ - int (*query_reparse_tag)(const unsigned int xid, struct cifs_tcon *tcon, - struct cifs_sb_info *cifs_sb, const char *path, - __u32 *reparse_tag); + /* query reparse point to determine which type of special file */ + int (*query_reparse_point)(const unsigned int xid, + struct cifs_tcon *tcon, + struct cifs_sb_info *cifs_sb, + const char *full_path, + u32 *tag, struct kvec *rsp, + int *rsp_buftype); /* get server index number */ int (*get_srv_inum)(const unsigned int xid, struct cifs_tcon *tcon, struct cifs_sb_info *cifs_sb, const char *full_path, u64 *uniqueid, @@ -388,9 +391,12 @@ struct smb_version_operations { const char *, const char *, struct cifs_sb_info *); /* query symlink target */ - int (*query_symlink)(const unsigned int, struct cifs_tcon *, - struct cifs_sb_info *, const char *, - char **, bool); + int (*query_symlink)(const unsigned int xid, + struct cifs_tcon *tcon, + struct cifs_sb_info *cifs_sb, + const char *full_path, + char **target_path, + struct kvec *rsp_iov); /* open a file for non-posix mounts */ int (*open)(const unsigned int xid, struct cifs_open_parms *oparms, __u32 *oplock, void *buf); diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c index 51e2916730cf..96a09818aa5b 100644 --- a/fs/smb/client/inode.c +++ b/fs/smb/client/inode.c @@ -428,7 +428,7 @@ int cifs_get_inode_info_unix(struct inode **pinode, if (!server->ops->query_symlink) return -EOPNOTSUPP; rc = server->ops->query_symlink(xid, tcon, cifs_sb, full_path, - &fattr.cf_symlink_target, false); + &fattr.cf_symlink_target, NULL); if (rc) { cifs_dbg(FYI, "%s: query_symlink: %d\n", __func__, rc); goto cgiiu_exit; @@ -988,17 +988,21 @@ static int query_reparse(struct cifs_open_info_data *data, { struct TCP_Server_Info *server = tcon->ses->server; struct cifs_sb_info *cifs_sb = CIFS_SB(sb); - bool reparse_point = data->reparse_point; + struct kvec rsp_iov, *iov = NULL; + int rsp_buftype = CIFS_NO_BUFFER; u32 tag = data->reparse_tag; int rc = 0; - if (!tag && server->ops->query_reparse_tag) { - server->ops->query_reparse_tag(xid, tcon, cifs_sb, - full_path, &tag); + if (!tag && server->ops->query_reparse_point) { + rc = server->ops->query_reparse_point(xid, tcon, cifs_sb, + full_path, &tag, + &rsp_iov, &rsp_buftype); + if (!rc) + iov = &rsp_iov; } switch ((data->reparse_tag = tag)) { case 0: /* SMB1 symlink */ - reparse_point = false; + iov = NULL; fallthrough; case IO_REPARSE_TAG_NFS: case IO_REPARSE_TAG_SYMLINK: @@ -1006,10 +1010,11 @@ static int query_reparse(struct cifs_open_info_data *data, rc = server->ops->query_symlink(xid, tcon, cifs_sb, full_path, &data->symlink_target, - reparse_point); + iov); } break; } + free_rsp_buf(rsp_buftype, rsp_iov.iov_base); return rc; } diff --git a/fs/smb/client/smb1ops.c b/fs/smb/client/smb1ops.c index 094ef4fe2219..9bf8735cdd1e 100644 --- a/fs/smb/client/smb1ops.c +++ b/fs/smb/client/smb1ops.c @@ -972,13 +972,16 @@ cifs_unix_dfs_readlink(const unsigned int xid, struct cifs_tcon *tcon, #endif } -static int -cifs_query_symlink(const unsigned int xid, struct cifs_tcon *tcon, - struct cifs_sb_info *cifs_sb, const char *full_path, - char **target_path, bool is_reparse_point) +static int cifs_query_symlink(const unsigned int xid, + struct cifs_tcon *tcon, + struct cifs_sb_info *cifs_sb, + const char *full_path, + char **target_path, + struct kvec *rsp_iov) { int rc; int oplock = 0; + bool is_reparse_point = !!rsp_iov; struct cifs_fid fid; struct cifs_open_parms oparms; diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c index 0f62bc373ad0..5eb2720f4aa7 100644 --- a/fs/smb/client/smb2ops.c +++ b/fs/smb/client/smb2ops.c @@ -2948,153 +2948,30 @@ parse_reparse_point(struct reparse_data_buffer *buf, } } -static int -smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon, - struct cifs_sb_info *cifs_sb, const char *full_path, - char **target_path, bool is_reparse_point) +static int smb2_query_symlink(const unsigned int xid, + struct cifs_tcon *tcon, + struct cifs_sb_info *cifs_sb, + const char *full_path, + char **target_path, + struct kvec *rsp_iov) { - int rc; - __le16 *utf16_path = NULL; - __u8 oplock = SMB2_OPLOCK_LEVEL_NONE; - struct cifs_open_parms oparms; - struct cifs_fid fid; - struct kvec err_iov = {NULL, 0}; - struct TCP_Server_Info *server = cifs_pick_channel(tcon->ses); - int flags = CIFS_CP_CREATE_CLOSE_OP; - struct smb_rqst rqst[3]; - int resp_buftype[3]; - struct kvec rsp_iov[3]; - struct kvec open_iov[SMB2_CREATE_IOV_SIZE]; - struct kvec io_iov[SMB2_IOCTL_IOV_SIZE]; - struct kvec close_iov[1]; - struct smb2_create_rsp *create_rsp; - struct smb2_ioctl_rsp *ioctl_rsp; - struct reparse_data_buffer *reparse_buf; - int create_options = is_reparse_point ? OPEN_REPARSE_POINT : 0; - u32 plen; + struct reparse_data_buffer *buf; + struct smb2_ioctl_rsp *io = rsp_iov->iov_base; + u32 plen = le32_to_cpu(io->OutputCount); cifs_dbg(FYI, "%s: path: %s\n", __func__, full_path); - *target_path = NULL; - - if (smb3_encryption_required(tcon)) - flags |= CIFS_TRANSFORM_REQ; - - memset(rqst, 0, sizeof(rqst)); - resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER; - memset(rsp_iov, 0, sizeof(rsp_iov)); - - utf16_path = cifs_convert_path_to_utf16(full_path, cifs_sb); - if (!utf16_path) - return -ENOMEM; - - /* Open */ - memset(&open_iov, 0, sizeof(open_iov)); - rqst[0].rq_iov = open_iov; - rqst[0].rq_nvec = SMB2_CREATE_IOV_SIZE; - - oparms = (struct cifs_open_parms) { - .tcon = tcon, - .path = full_path, - .desired_access = FILE_READ_ATTRIBUTES, - .disposition = FILE_OPEN, - .create_options = cifs_create_options(cifs_sb, create_options), - .fid = &fid, - }; - - rc = SMB2_open_init(tcon, server, - &rqst[0], &oplock, &oparms, utf16_path); - if (rc) - goto querty_exit; - smb2_set_next_command(tcon, &rqst[0]); - - - /* IOCTL */ - memset(&io_iov, 0, sizeof(io_iov)); - rqst[1].rq_iov = io_iov; - rqst[1].rq_nvec = SMB2_IOCTL_IOV_SIZE; - - rc = SMB2_ioctl_init(tcon, server, - &rqst[1], fid.persistent_fid, - fid.volatile_fid, FSCTL_GET_REPARSE_POINT, NULL, 0, - CIFSMaxBufSize - - MAX_SMB2_CREATE_RESPONSE_SIZE - - MAX_SMB2_CLOSE_RESPONSE_SIZE); - if (rc) - goto querty_exit; - - smb2_set_next_command(tcon, &rqst[1]); - smb2_set_related(&rqst[1]); - - - /* Close */ - memset(&close_iov, 0, sizeof(close_iov)); - rqst[2].rq_iov = close_iov; - rqst[2].rq_nvec = 1; - - rc = SMB2_close_init(tcon, server, - &rqst[2], COMPOUND_FID, COMPOUND_FID, false); - if (rc) - goto querty_exit; - - smb2_set_related(&rqst[2]); - - rc = compound_send_recv(xid, tcon->ses, server, - flags, 3, rqst, - resp_buftype, rsp_iov); - - create_rsp = rsp_iov[0].iov_base; - if (create_rsp && create_rsp->hdr.Status) - err_iov = rsp_iov[0]; - ioctl_rsp = rsp_iov[1].iov_base; - - /* - * Open was successful and we got an ioctl response. - */ - if ((rc == 0) && (is_reparse_point)) { - /* See MS-FSCC 2.3.23 */ - - reparse_buf = (struct reparse_data_buffer *) - ((char *)ioctl_rsp + - le32_to_cpu(ioctl_rsp->OutputOffset)); - plen = le32_to_cpu(ioctl_rsp->OutputCount); - - if (plen + le32_to_cpu(ioctl_rsp->OutputOffset) > - rsp_iov[1].iov_len) { - cifs_tcon_dbg(VFS, "srv returned invalid ioctl len: %d\n", - plen); - rc = -EIO; - goto querty_exit; - } - - rc = parse_reparse_point(reparse_buf, plen, target_path, - cifs_sb); - goto querty_exit; - } - - if (!rc || !err_iov.iov_base) { - rc = -ENOENT; - goto querty_exit; - } - - rc = smb2_parse_symlink_response(cifs_sb, &err_iov, target_path); - - querty_exit: - cifs_dbg(FYI, "query symlink rc %d\n", rc); - kfree(utf16_path); - SMB2_open_free(&rqst[0]); - SMB2_ioctl_free(&rqst[1]); - SMB2_close_free(&rqst[2]); - free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base); - free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base); - free_rsp_buf(resp_buftype[2], rsp_iov[2].iov_base); - return rc; + buf = (struct reparse_data_buffer *)((u8 *)io + + le32_to_cpu(io->OutputOffset)); + return parse_reparse_point(buf, plen, target_path, cifs_sb); } -int -smb2_query_reparse_tag(const unsigned int xid, struct cifs_tcon *tcon, - struct cifs_sb_info *cifs_sb, const char *full_path, - __u32 *tag) +static int smb2_query_reparse_point(const unsigned int xid, + struct cifs_tcon *tcon, + struct cifs_sb_info *cifs_sb, + const char *full_path, + u32 *tag, struct kvec *rsp, + int *rsp_buftype) { int rc; __le16 *utf16_path = NULL; @@ -3205,6 +3082,9 @@ smb2_query_reparse_tag(const unsigned int xid, struct cifs_tcon *tcon, goto query_rp_exit; } *tag = le32_to_cpu(reparse_buf->ReparseTag); + *rsp = rsp_iov[1]; + *rsp_buftype = resp_buftype[1]; + resp_buftype[1] = CIFS_NO_BUFFER; } query_rp_exit: @@ -5503,7 +5383,7 @@ struct smb_version_operations smb30_operations = { .echo = SMB2_echo, .query_path_info = smb2_query_path_info, /* WSL tags introduced long after smb2.1, enable for SMB3, 3.11 only */ - .query_reparse_tag = smb2_query_reparse_tag, + .query_reparse_point = smb2_query_reparse_point, .get_srv_inum = smb2_get_srv_inum, .query_file_info = smb2_query_file_info, .set_path_size = smb2_set_path_size, @@ -5616,7 +5496,7 @@ struct smb_version_operations smb311_operations = { .can_echo = smb2_can_echo, .echo = SMB2_echo, .query_path_info = smb2_query_path_info, - .query_reparse_tag = smb2_query_reparse_tag, + .query_reparse_point = smb2_query_reparse_point, .get_srv_inum = smb2_get_srv_inum, .query_file_info = smb2_query_file_info, .set_path_size = smb2_set_path_size, From patchwork Thu Aug 17 15:34:08 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paulo Alcantara X-Patchwork-Id: 13356728 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 0A9CBC3065A for ; Thu, 17 Aug 2023 15:36:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1352316AbjHQPgN (ORCPT ); Thu, 17 Aug 2023 11:36:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38946 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1352654AbjHQPfn (ORCPT ); Thu, 17 Aug 2023 11:35:43 -0400 Received: from mx.manguebit.com (mx.manguebit.com [IPv6:2a01:4f8:1c1e:a2ae::2]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3DC5630D8 for ; Thu, 17 Aug 2023 08:35:42 -0700 (PDT) From: Paulo Alcantara DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=manguebit.com; s=dkim; t=1692286540; 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=D5SRCLltgqEHZcEHjqTcOLrWrO6ltmayS//elFhRyvY=; b=Mu+osz2popbSH/qK19T2D+mRWd+ZEAh0UuW5XYnHoqB52FC5JXPc2Mv3z9nEeWzJOt+P/D /a/PSjQjZtyLB/bE6a6QtuvbnjWABjrzOHpmjF+2drcQiGmEyHja0W74kK+KZLpGR/6Hgu C6BMfZPmy0gObgV8n0uLGXlaeXL4G7E295h+tsp39/o6hUAmIVUG6HxtsikJX4yZwkfpvN 8tOnjtHhHEQo8q0FvBR5GZjQUgNrXJASwGgRFMyeChwtTa8Kenj1yWE++tNDqL7eGhvDTN iJBodlTyVLnLY3aF7nfccq4LlPItCOsa0wLgxgX22Xl3WWw3CQPEFzyu5FGhPg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=manguebit.com; s=dkim; t=1692286540; 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=D5SRCLltgqEHZcEHjqTcOLrWrO6ltmayS//elFhRyvY=; b=ME+4xnS7+wHzKmlLN8oY/sLUdCEAMc3bNGDT85xwIfthu2SftbB/eepN6XLmDwJHOjwDeg wExbWBc6v1sxZRq/mAO3eDxZ/IkzF6TTGPgz9LlCsUvU90xbF5nHeCE8wEeHPuSV10qdO2 rkdG6Md2DUfxLRlmg/S5cckyVMNxddYI0JTJpq3SDQ27SrZCFg54MCAk82otwzP1HsNtG8 k9rFPz6ZS65A6Umt+yBcGjMBvoAEnjw5s3GTEDTbNi/M5uJwA4rurGXV+8z90KQF5tIZVp hBJXS/sVLJLhm61o92P+AKA1PlN+whpCwD2yXoF/lD5p9z2jYsoQ8LU129MhBQ== ARC-Authentication-Results: i=1; ORIGINATING; auth=pass smtp.auth=pc@manguebit.com smtp.mailfrom=pc@manguebit.com ARC-Seal: i=1; s=dkim; d=manguebit.com; t=1692286540; a=rsa-sha256; cv=none; b=ZcqA6umjtJPXlh1pyGz2Ee61qsDdD6rPSlzpKC88NHR48/uYRj7+xO9PALF0dC4Y/4QPx+ Qpv/wTVSD5AyFMOKdGSVpnyXDfEK9+vfVTQhFP1s59TapWrj9x88MPmMCKqCbgmYqqfpK7 5Tr8ZyJN3prX0WAGd1Yfg/MmHkvuF73tPnf37EFDryRm/sbC56EzHTX/78u6nZDzzSnfbw 8FSitvdkOGoPURiiZjqkCdC2urba0upYTBMmdcpZeyuUmj1PUGTs1tUnbIR2SaqpNLxxAN 08hErAjYXpUYTcSR132vbckL1g2qpEj31ZxnWoGagi3J0eGue+7sCih0nKUWTA== To: smfrench@gmail.com Cc: linux-cifs@vger.kernel.org, Paulo Alcantara Subject: [PATCH 10/17] smb: client: query reparse points in older dialects Date: Thu, 17 Aug 2023 12:34:08 -0300 Message-ID: <20230817153416.28083-11-pc@manguebit.com> In-Reply-To: <20230817153416.28083-1-pc@manguebit.com> References: <20230817153416.28083-1-pc@manguebit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Enable the client to query reparse points in SMB2+. Signed-off-by: Paulo Alcantara (SUSE) --- fs/smb/client/smb2ops.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c index 5eb2720f4aa7..91c7b7e52a72 100644 --- a/fs/smb/client/smb2ops.c +++ b/fs/smb/client/smb2ops.c @@ -5178,6 +5178,7 @@ struct smb_version_operations smb20_operations = { .can_echo = smb2_can_echo, .echo = SMB2_echo, .query_path_info = smb2_query_path_info, + .query_reparse_point = smb2_query_reparse_point, .get_srv_inum = smb2_get_srv_inum, .query_file_info = smb2_query_file_info, .set_path_size = smb2_set_path_size, @@ -5279,6 +5280,7 @@ struct smb_version_operations smb21_operations = { .can_echo = smb2_can_echo, .echo = SMB2_echo, .query_path_info = smb2_query_path_info, + .query_reparse_point = smb2_query_reparse_point, .get_srv_inum = smb2_get_srv_inum, .query_file_info = smb2_query_file_info, .set_path_size = smb2_set_path_size, From patchwork Thu Aug 17 15:34:09 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paulo Alcantara X-Patchwork-Id: 13356731 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 3E608C3065E for ; Thu, 17 Aug 2023 15:36:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1352320AbjHQPgO (ORCPT ); Thu, 17 Aug 2023 11:36:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38982 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1352348AbjHQPfr (ORCPT ); Thu, 17 Aug 2023 11:35:47 -0400 Received: from mx.manguebit.com (mx.manguebit.com [167.235.159.17]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6CB942D6D for ; Thu, 17 Aug 2023 08:35:44 -0700 (PDT) From: Paulo Alcantara DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=manguebit.com; s=dkim; t=1692286543; 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=4d17a1RbI0rCZpounCEPQdS7sJHp+LafngJafYOuqAU=; b=dJ/7MHgOnm56pHqVsnzb7olqgjA9afpFqeac6jWQxhcCp1ZczzquFw3agO0OeRALvXZska f/H9K36Vj47Rd3e1o3/4b7IDQQN8HQFShJYxpndoHbh1+emyT+wxxcDdt1T9Q+Gje9zFoU sVTo4QVeIB2aZFGs1zDEV+EASqgXXCUUy3TMJzKJEWKLyMzwwjW59bwlKK6a00sTf9wSVD EOvNhY7XCjnZKEeiGg1RkixP9NuaBOdeTh52MnXeKXpdMakokbEwysr50OZkSKV1BWEkBU aVcqrZjcgb12XLVvb/MdJWDdz6qYlizS7mJpvXasQJ3WrysicxcjDGavjGL+eQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=manguebit.com; s=dkim; t=1692286543; 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=4d17a1RbI0rCZpounCEPQdS7sJHp+LafngJafYOuqAU=; b=LbI50NQXZBzrNZS322z/ap+znr8TSbR1zN+xDY9hJll0insrqH2PcLfLmnqjOHng0u8Fn/ qeI99sqmaoUBWCIZQAEfMDMQNNLOalcfpa1RzKbXt8XPnF171rURRdbBH8n3xFVlUNvKub Oub3zKve6iW1xcO3RwLltc3XJ66w6kH1lTCfl+IVel0xiHuXpsygt+ZV4ldRQg7nbX5AYr CDFyYLOVqjhKVzLXu25BjzqbD3TeAdwLYss38LR48LR73hmF5RGnnxnetdgYsBXnA3will wo5pNRDuBRkrmifyqpMjl49ohp/DkF+nH9xhD8olt8Qx4VKi6IvW67SnaNStiw== ARC-Authentication-Results: i=1; ORIGINATING; auth=pass smtp.auth=pc@manguebit.com smtp.mailfrom=pc@manguebit.com ARC-Seal: i=1; s=dkim; d=manguebit.com; t=1692286543; a=rsa-sha256; cv=none; b=TCFiRlbiWY+uWYE6nJ1Seu2so43FJ/PKU7MPlxZXcNuoUGARoumnMjNipr4RBBWdZdzjB4 FxYnJO9Am7bsxAX/Lk7PRwYJZ3vhjLnzYZ/MhCksh1hZxlTohm89Dm9gaJWmsercQMPZdh as6kLdADp3nO5g9EVvNaD6yweF0ttQLQVY2xIvthGbNUypt/GDhxMT65XsTbJmSe3q1p+k u15ZvrXsRFamvhuCSjwGCxrow1UbM7pVqY5FxLqv7dg+T11Ok9iXM/2szLzsEfR0AgWmY6 GafgjvT0yHRn1hh+CnZQTuXV2fOhwzN+N2apKRpCAn0gdRaQx7q2/cyU1xERmw== To: smfrench@gmail.com Cc: linux-cifs@vger.kernel.org, Paulo Alcantara Subject: [PATCH 11/17] smb: cilent: set reparse mount points as automounts Date: Thu, 17 Aug 2023 12:34:09 -0300 Message-ID: <20230817153416.28083-12-pc@manguebit.com> In-Reply-To: <20230817153416.28083-1-pc@manguebit.com> References: <20230817153416.28083-1-pc@manguebit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org By doing so we can selectively mark those submounts as 'noserverino' rather than whole mount and thus avoiding inode collisions in them. Consider a "test" SMB share that has two mounted NTFS volumes (vol0 & vol1) inside it. * Before patch $ mount.cifs //srv/test /mnt/1 -o ...,serverino $ ls -li /mnt/1/vol0 total 1 281474976710693 drwxr-xr-x 2 root root 0 Jul 15 00:23 $RECYCLE.BIN 281474976710696 drwxr-xr-x 2 root root 0 Jul 18 18:23 System Volume... 281474976710699 -rwxr-xr-x 1 root root 0 Aug 14 21:53 f0 281474976710700 -rwxr-xr-x 1 root root 0 Aug 15 18:52 f2 281474976710698 drwxr-xr-x 2 root root 0 Aug 12 19:39 foo 281474976710692 -rwxr-xr-x 1 root root 5 Aug 4 21:18 vol0_f0.txt $ ls -li /mnt/1/vol1 total 0 281474976710693 drwxr-xr-x 2 root root 0 Jul 15 00:23 $RECYCLE.BIN 281474976710696 drwxr-xr-x 2 root root 0 Jul 18 18:23 System Volume... 281474976710698 drwxr-xr-x 2 root root 0 Aug 12 19:39 bar 281474976710699 -rwxr-xr-x 1 root root 0 Aug 14 22:03 f0 281474976710700 -rwxr-xr-x 1 root root 0 Aug 14 22:52 f1 281474976710692 -rwxr-xr-x 1 root root 0 Jul 15 00:23 vol1_f0.txt * After patch $ mount.cifs //srv/test /mnt/1 -o ...,serverino $ ls -li /mnt/1/vol0 total 1 590 drwxr-xr-x 2 root root 0 Jul 15 00:23 $RECYCLE.BIN 594 drwxr-xr-x 2 root root 0 Jul 18 18:23 System Volume Information 591 -rwxr-xr-x 1 root root 0 Aug 14 21:53 f0 592 -rwxr-xr-x 1 root root 0 Aug 15 18:52 f2 593 drwxr-xr-x 2 root root 0 Aug 12 19:39 foo 595 -rwxr-xr-x 1 root root 5 Aug 4 21:18 vol0_f0.txt $ ls -li /mnt/1/vol1 total 0 596 drwxr-xr-x 2 root root 0 Jul 15 00:23 $RECYCLE.BIN 600 drwxr-xr-x 2 root root 0 Jul 18 18:23 System Volume Information 597 drwxr-xr-x 2 root root 0 Aug 12 19:39 bar 598 -rwxr-xr-x 1 root root 0 Aug 14 22:03 f0 599 -rwxr-xr-x 1 root root 0 Aug 14 22:52 f1 601 -rwxr-xr-x 1 root root 0 Jul 15 00:23 vol1_f0.txt Signed-off-by: Paulo Alcantara (SUSE) --- fs/smb/client/cifsglob.h | 2 +- fs/smb/client/inode.c | 352 +++++++++++++++++++++----------------- fs/smb/client/namespace.c | 19 +- fs/smb/client/readdir.c | 1 + 4 files changed, 198 insertions(+), 176 deletions(-) diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h index 639a61417b08..6d5fa0351dce 100644 --- a/fs/smb/client/cifsglob.h +++ b/fs/smb/client/cifsglob.h @@ -1094,7 +1094,7 @@ cap_unix(struct cifs_ses *ses) * inode with new info */ -#define CIFS_FATTR_DFS_REFERRAL 0x1 +#define CIFS_FATTR_JUNCTION 0x1 #define CIFS_FATTR_DELETE_PENDING 0x2 #define CIFS_FATTR_NEED_REVAL 0x4 #define CIFS_FATTR_INO_COLLISION 0x8 diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c index 96a09818aa5b..ba17356aa7bb 100644 --- a/fs/smb/client/inode.c +++ b/fs/smb/client/inode.c @@ -214,7 +214,7 @@ cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr) } spin_unlock(&inode->i_lock); - if (fattr->cf_flags & CIFS_FATTR_DFS_REFERRAL) + if (fattr->cf_flags & CIFS_FATTR_JUNCTION) inode->i_flags |= S_AUTOMOUNT; if (inode->i_state & I_NEW) cifs_set_ops(inode); @@ -323,14 +323,14 @@ cifs_unix_basic_to_fattr(struct cifs_fattr *fattr, FILE_UNIX_BASIC_INFO *info, * * Needed to setup cifs_fattr data for the directory which is the * junction to the new submount (ie to setup the fake directory - * which represents a DFS referral). + * which represents a DFS referral or reparse mount point). */ -static void -cifs_create_dfs_fattr(struct cifs_fattr *fattr, struct super_block *sb) +static void cifs_create_junction_fattr(struct cifs_fattr *fattr, + struct super_block *sb) { struct cifs_sb_info *cifs_sb = CIFS_SB(sb); - cifs_dbg(FYI, "creating fake fattr for DFS referral\n"); + cifs_dbg(FYI, "%s: creating fake fattr\n", __func__); memset(fattr, 0, sizeof(*fattr)); fattr->cf_mode = S_IFDIR | S_IXUGO | S_IRWXU; @@ -339,7 +339,33 @@ cifs_create_dfs_fattr(struct cifs_fattr *fattr, struct super_block *sb) ktime_get_coarse_real_ts64(&fattr->cf_mtime); fattr->cf_atime = fattr->cf_ctime = fattr->cf_mtime; fattr->cf_nlink = 2; - fattr->cf_flags = CIFS_FATTR_DFS_REFERRAL; + fattr->cf_flags = CIFS_FATTR_JUNCTION; +} + +/* Update inode with final fattr data */ +static int update_inode_info(struct super_block *sb, + struct cifs_fattr *fattr, + struct inode **inode) +{ + struct cifs_sb_info *cifs_sb = CIFS_SB(sb); + int rc = 0; + + if (!*inode) { + *inode = cifs_iget(sb, fattr); + if (!*inode) + rc = -ENOMEM; + return rc; + } + /* We already have inode, update it. + * + * If file type or uniqueid is different, return error. + */ + if (unlikely((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) && + CIFS_I(*inode)->uniqueid != fattr->cf_uniqueid)) { + CIFS_I(*inode)->time = 0; /* force reval */ + return -ESTALE; + } + return cifs_fattr_to_inode(*inode, fattr); } #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY @@ -369,7 +395,7 @@ cifs_get_file_info_unix(struct file *filp) if (!rc) { cifs_unix_basic_to_fattr(&fattr, &find_data, cifs_sb); } else if (rc == -EREMOTE) { - cifs_create_dfs_fattr(&fattr, inode->i_sb); + cifs_create_junction_fattr(&fattr, inode->i_sb); rc = 0; } else goto cifs_gfiunix_out; @@ -381,17 +407,18 @@ cifs_get_file_info_unix(struct file *filp) return rc; } -int cifs_get_inode_info_unix(struct inode **pinode, - const unsigned char *full_path, - struct super_block *sb, unsigned int xid) +static int cifs_get_unix_fattr(const unsigned char *full_path, + struct super_block *sb, + struct cifs_fattr *fattr, + struct inode **pinode, + const unsigned int xid) { - int rc; + struct TCP_Server_Info *server; + struct cifs_sb_info *cifs_sb = CIFS_SB(sb); FILE_UNIX_BASIC_INFO find_data; - struct cifs_fattr fattr; struct cifs_tcon *tcon; - struct TCP_Server_Info *server; struct tcon_link *tlink; - struct cifs_sb_info *cifs_sb = CIFS_SB(sb); + int rc, tmprc; cifs_dbg(FYI, "Getting info on %s\n", full_path); @@ -408,59 +435,61 @@ int cifs_get_inode_info_unix(struct inode **pinode, cifs_put_tlink(tlink); if (!rc) { - cifs_unix_basic_to_fattr(&fattr, &find_data, cifs_sb); + cifs_unix_basic_to_fattr(fattr, &find_data, cifs_sb); } else if (rc == -EREMOTE) { - cifs_create_dfs_fattr(&fattr, sb); + cifs_create_junction_fattr(fattr, sb); rc = 0; } else { return rc; } + if (!*pinode) + cifs_fill_uniqueid(sb, fattr); + /* check for Minshall+French symlinks */ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) { - int tmprc = check_mf_symlink(xid, tcon, cifs_sb, &fattr, - full_path); - if (tmprc) - cifs_dbg(FYI, "check_mf_symlink: %d\n", tmprc); + tmprc = check_mf_symlink(xid, tcon, cifs_sb, fattr, full_path); + cifs_dbg(FYI, "check_mf_symlink: %d\n", tmprc); } - if (S_ISLNK(fattr.cf_mode) && !fattr.cf_symlink_target) { + if (S_ISLNK(fattr->cf_mode) && !fattr->cf_symlink_target) { if (!server->ops->query_symlink) return -EOPNOTSUPP; - rc = server->ops->query_symlink(xid, tcon, cifs_sb, full_path, - &fattr.cf_symlink_target, NULL); - if (rc) { - cifs_dbg(FYI, "%s: query_symlink: %d\n", __func__, rc); - goto cgiiu_exit; - } + rc = server->ops->query_symlink(xid, tcon, + cifs_sb, full_path, + &fattr->cf_symlink_target, + NULL); + cifs_dbg(FYI, "%s: query_symlink: %d\n", __func__, rc); } + return rc; +} - if (*pinode == NULL) { - /* get new inode */ - cifs_fill_uniqueid(sb, &fattr); - *pinode = cifs_iget(sb, &fattr); - if (!*pinode) - rc = -ENOMEM; - } else { - /* we already have inode, update it */ +int cifs_get_inode_info_unix(struct inode **pinode, + const unsigned char *full_path, + struct super_block *sb, unsigned int xid) +{ + struct cifs_fattr fattr = {}; + int rc; - /* if uniqueid is different, return error */ - if (unlikely(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM && - CIFS_I(*pinode)->uniqueid != fattr.cf_uniqueid)) { - CIFS_I(*pinode)->time = 0; /* force reval */ - rc = -ESTALE; - goto cgiiu_exit; - } + rc = cifs_get_unix_fattr(full_path, sb, &fattr, pinode, xid); + if (rc) + goto out; - /* if filetype is different, return error */ - rc = cifs_fattr_to_inode(*pinode, &fattr); - } - -cgiiu_exit: + rc = update_inode_info(sb, &fattr, pinode); +out: kfree(fattr.cf_symlink_target); return rc; } #else +static inline int cifs_get_unix_fattr(const unsigned char *full_path, + struct super_block *sb, + struct cifs_fattr *fattr, + struct inode **pinode, + const unsigned int xid) +{ + return -EOPNOTSUPP; +} + int cifs_get_inode_info_unix(struct inode **pinode, const unsigned char *full_path, struct super_block *sb, unsigned int xid) @@ -826,7 +855,7 @@ cifs_get_file_info(struct file *filp) cifs_open_info_to_fattr(&fattr, &data, inode->i_sb); break; case -EREMOTE: - cifs_create_dfs_fattr(&fattr, inode->i_sb); + cifs_create_junction_fattr(&fattr, inode->i_sb); rc = 0; break; case -EOPNOTSUPP: @@ -979,12 +1008,12 @@ static inline bool is_inode_cache_good(struct inode *ino) return ino && CIFS_CACHE_READ(CIFS_I(ino)) && CIFS_I(ino)->time != 0; } -static int query_reparse(struct cifs_open_info_data *data, - struct super_block *sb, - const unsigned int xid, - struct cifs_tcon *tcon, - const char *full_path, - struct cifs_fattr *fattr) +static int reparse_info_to_fattr(struct cifs_open_info_data *data, + struct super_block *sb, + const unsigned int xid, + struct cifs_tcon *tcon, + const char *full_path, + struct cifs_fattr *fattr) { struct TCP_Server_Info *server = tcon->ses->server; struct cifs_sb_info *cifs_sb = CIFS_SB(sb); @@ -1013,21 +1042,29 @@ static int query_reparse(struct cifs_open_info_data *data, iov); } break; + case IO_REPARSE_TAG_MOUNT_POINT: + cifs_create_junction_fattr(fattr, sb); + goto out; } + + cifs_open_info_to_fattr(fattr, data, sb); +out: free_rsp_buf(rsp_buftype, rsp_iov.iov_base); return rc; } -int cifs_get_inode_info(struct inode **inode, const char *full_path, - struct cifs_open_info_data *data, struct super_block *sb, int xid, - const struct cifs_fid *fid) +static int cifs_get_fattr(struct cifs_open_info_data *data, + struct super_block *sb, int xid, + const struct cifs_fid *fid, + struct cifs_fattr *fattr, + struct inode **inode, + const char *full_path) { - struct cifs_tcon *tcon; - struct TCP_Server_Info *server; - struct tcon_link *tlink; - struct cifs_sb_info *cifs_sb = CIFS_SB(sb); - struct cifs_fattr fattr = {0}; struct cifs_open_info_data tmp_data = {}; + struct cifs_tcon *tcon; + struct TCP_Server_Info *server; + struct tcon_link *tlink; + struct cifs_sb_info *cifs_sb = CIFS_SB(sb); void *smb1_backup_rsp_buf = NULL; int rc = 0; int tmprc = 0; @@ -1043,10 +1080,6 @@ int cifs_get_inode_info(struct inode **inode, const char *full_path, */ if (!data) { - if (is_inode_cache_good(*inode)) { - cifs_dbg(FYI, "No need to revalidate cached inode sizes\n"); - goto out; - } rc = server->ops->query_path_info(xid, tcon, cifs_sb, full_path, &tmp_data); data = &tmp_data; @@ -1064,15 +1097,15 @@ int cifs_get_inode_info(struct inode **inode, const char *full_path, * special file type e.g. symlink or fifo or char etc. */ if (cifs_open_data_reparse(data)) { - rc = query_reparse(data, sb, xid, tcon, - full_path, &fattr); + rc = reparse_info_to_fattr(data, sb, xid, tcon, + full_path, fattr); + } else { + cifs_open_info_to_fattr(fattr, data, sb); } - if (!rc) - cifs_open_info_to_fattr(&fattr, data, sb); break; case -EREMOTE: /* DFS link, no metadata available on this server */ - cifs_create_dfs_fattr(&fattr, sb); + cifs_create_junction_fattr(fattr, sb); rc = 0; break; case -EACCES: @@ -1102,8 +1135,8 @@ int cifs_get_inode_info(struct inode **inode, const char *full_path, fdi = (FILE_DIRECTORY_INFO *)fi; si = (SEARCH_ID_FULL_DIR_INFO *)fi; - cifs_dir_info_to_fattr(&fattr, fdi, cifs_sb); - fattr.cf_uniqueid = le64_to_cpu(si->UniqueId); + cifs_dir_info_to_fattr(fattr, fdi, cifs_sb); + fattr->cf_uniqueid = le64_to_cpu(si->UniqueId); /* uniqueid set, skip get inum step */ goto handle_mnt_opt; } else { @@ -1120,10 +1153,10 @@ int cifs_get_inode_info(struct inode **inode, const char *full_path, } /* - * 3. Get or update inode number (fattr.cf_uniqueid) + * 3. Get or update inode number (fattr->cf_uniqueid) */ - cifs_set_fattr_ino(xid, tcon, sb, inode, full_path, data, &fattr); + cifs_set_fattr_ino(xid, tcon, sb, inode, full_path, data, fattr); /* * 4. Tweak fattr based on mount options @@ -1132,17 +1165,17 @@ int cifs_get_inode_info(struct inode **inode, const char *full_path, handle_mnt_opt: #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */ /* query for SFU type info if supported and needed */ - if (fattr.cf_cifsattrs & ATTR_SYSTEM && - cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { - tmprc = cifs_sfu_type(&fattr, full_path, cifs_sb, xid); + if ((fattr->cf_cifsattrs & ATTR_SYSTEM) && + (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)) { + tmprc = cifs_sfu_type(fattr, full_path, cifs_sb, xid); if (tmprc) cifs_dbg(FYI, "cifs_sfu_type failed: %d\n", tmprc); } /* fill in 0777 bits from ACL */ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID) { - rc = cifs_acl_to_fattr(cifs_sb, &fattr, *inode, true, - full_path, fid); + rc = cifs_acl_to_fattr(cifs_sb, fattr, *inode, + true, full_path, fid); if (rc == -EREMOTE) rc = 0; if (rc) { @@ -1151,8 +1184,8 @@ int cifs_get_inode_info(struct inode **inode, const char *full_path, goto out; } } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { - rc = cifs_acl_to_fattr(cifs_sb, &fattr, *inode, false, - full_path, fid); + rc = cifs_acl_to_fattr(cifs_sb, fattr, *inode, + false, full_path, fid); if (rc == -EREMOTE) rc = 0; if (rc) { @@ -1164,58 +1197,57 @@ int cifs_get_inode_info(struct inode **inode, const char *full_path, /* fill in remaining high mode bits e.g. SUID, VTX */ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) - cifs_sfu_mode(&fattr, full_path, cifs_sb, xid); + cifs_sfu_mode(fattr, full_path, cifs_sb, xid); /* check for Minshall+French symlinks */ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) { - tmprc = check_mf_symlink(xid, tcon, cifs_sb, &fattr, - full_path); - if (tmprc) - cifs_dbg(FYI, "check_mf_symlink: %d\n", tmprc); + tmprc = check_mf_symlink(xid, tcon, cifs_sb, fattr, full_path); + cifs_dbg(FYI, "check_mf_symlink: %d\n", tmprc); } - /* - * 5. Update inode with final fattr data - */ - - if (!*inode) { - *inode = cifs_iget(sb, &fattr); - if (!*inode) - rc = -ENOMEM; - } else { - /* we already have inode, update it */ - - /* if uniqueid is different, return error */ - if (unlikely(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM && - CIFS_I(*inode)->uniqueid != fattr.cf_uniqueid)) { - CIFS_I(*inode)->time = 0; /* force reval */ - rc = -ESTALE; - goto out; - } - /* if filetype is different, return error */ - rc = cifs_fattr_to_inode(*inode, &fattr); - } out: cifs_buf_release(smb1_backup_rsp_buf); cifs_put_tlink(tlink); cifs_free_open_info(&tmp_data); + return rc; +} + +int cifs_get_inode_info(struct inode **inode, + const char *full_path, + struct cifs_open_info_data *data, + struct super_block *sb, int xid, + const struct cifs_fid *fid) +{ + struct cifs_fattr fattr = {}; + int rc; + + if (is_inode_cache_good(*inode)) { + cifs_dbg(FYI, "No need to revalidate cached inode sizes\n"); + return 0; + } + + rc = cifs_get_fattr(data, sb, xid, fid, &fattr, inode, full_path); + if (rc) + goto out; + + rc = update_inode_info(sb, &fattr, inode); +out: kfree(fattr.cf_symlink_target); return rc; } -int -smb311_posix_get_inode_info(struct inode **inode, - const char *full_path, - struct super_block *sb, unsigned int xid) +static int smb311_posix_get_fattr(struct cifs_fattr *fattr, + const char *full_path, + struct super_block *sb, + const unsigned int xid) { + struct cifs_open_info_data data = {}; + struct cifs_sb_info *cifs_sb = CIFS_SB(sb); struct cifs_tcon *tcon; struct tcon_link *tlink; - struct cifs_sb_info *cifs_sb = CIFS_SB(sb); - struct cifs_fattr fattr = {0}; - struct cifs_open_info_data data = {}; struct cifs_sid owner, group; - int rc = 0; - int tmprc = 0; + int tmprc; + int rc; tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) @@ -1226,11 +1258,6 @@ smb311_posix_get_inode_info(struct inode **inode, * 1. Fetch file metadata */ - if (is_inode_cache_good(*inode)) { - cifs_dbg(FYI, "No need to revalidate cached inode sizes\n"); - goto out; - } - rc = smb311_posix_query_path_info(xid, tcon, cifs_sb, full_path, &data, &owner, &group); @@ -1241,11 +1268,11 @@ smb311_posix_get_inode_info(struct inode **inode, switch (rc) { case 0: - smb311_posix_info_to_fattr(&fattr, &data, &owner, &group, sb); + smb311_posix_info_to_fattr(fattr, &data, &owner, &group, sb); break; case -EREMOTE: /* DFS link, no metadata available on this server */ - cifs_create_dfs_fattr(&fattr, sb); + cifs_create_junction_fattr(fattr, sb); rc = 0; break; case -EACCES: @@ -1261,49 +1288,42 @@ smb311_posix_get_inode_info(struct inode **inode, goto out; } - /* * 3. Tweak fattr based on mount options */ - /* check for Minshall+French symlinks */ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) { - tmprc = check_mf_symlink(xid, tcon, cifs_sb, &fattr, - full_path); - if (tmprc) - cifs_dbg(FYI, "check_mf_symlink: %d\n", tmprc); + tmprc = check_mf_symlink(xid, tcon, cifs_sb, fattr, full_path); + cifs_dbg(FYI, "check_mf_symlink: %d\n", tmprc); } - /* - * 4. Update inode with final fattr data - */ - - if (!*inode) { - *inode = cifs_iget(sb, &fattr); - if (!*inode) - rc = -ENOMEM; - } else { - /* we already have inode, update it */ - - /* if uniqueid is different, return error */ - if (unlikely(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM && - CIFS_I(*inode)->uniqueid != fattr.cf_uniqueid)) { - CIFS_I(*inode)->time = 0; /* force reval */ - rc = -ESTALE; - goto out; - } - - /* if filetype is different, return error */ - rc = cifs_fattr_to_inode(*inode, &fattr); - } out: cifs_put_tlink(tlink); cifs_free_open_info(&data); + return rc; +} + +int smb311_posix_get_inode_info(struct inode **inode, const char *full_path, + struct super_block *sb, const unsigned int xid) +{ + struct cifs_fattr fattr = {}; + int rc; + + if (is_inode_cache_good(*inode)) { + cifs_dbg(FYI, "No need to revalidate cached inode sizes\n"); + return 0; + } + + rc = smb311_posix_get_fattr(&fattr, full_path, sb, xid); + if (rc) + goto out; + + rc = update_inode_info(sb, &fattr, inode); +out: kfree(fattr.cf_symlink_target); return rc; } - static const struct inode_operations cifs_ipc_inode_ops = { .lookup = cifs_lookup, }; @@ -1407,13 +1427,14 @@ cifs_iget(struct super_block *sb, struct cifs_fattr *fattr) /* gets root inode */ struct inode *cifs_root_iget(struct super_block *sb) { - unsigned int xid; struct cifs_sb_info *cifs_sb = CIFS_SB(sb); - struct inode *inode = NULL; - long rc; + struct cifs_fattr fattr = {}; struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); + struct inode *inode = NULL; + unsigned int xid; char *path = NULL; int len; + int rc; if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH) && cifs_sb->prepath) { @@ -1431,21 +1452,29 @@ struct inode *cifs_root_iget(struct super_block *sb) xid = get_xid(); if (tcon->unix_ext) { - rc = cifs_get_inode_info_unix(&inode, path, sb, xid); + rc = cifs_get_unix_fattr(path, sb, &fattr, &inode, xid); /* some servers mistakenly claim POSIX support */ if (rc != -EOPNOTSUPP) - goto iget_no_retry; + goto iget_root; cifs_dbg(VFS, "server does not support POSIX extensions\n"); tcon->unix_ext = false; } convert_delimiter(path, CIFS_DIR_SEP(cifs_sb)); if (tcon->posix_extensions) - rc = smb311_posix_get_inode_info(&inode, path, sb, xid); + rc = smb311_posix_get_fattr(&fattr, path, sb, xid); else - rc = cifs_get_inode_info(&inode, path, NULL, sb, xid, NULL); + rc = cifs_get_fattr(NULL, sb, xid, NULL, &fattr, &inode, path); + +iget_root: + if (!rc) { + if (fattr.cf_flags & CIFS_FATTR_JUNCTION) { + fattr.cf_flags &= ~CIFS_FATTR_JUNCTION; + cifs_autodisable_serverino(cifs_sb); + } + inode = cifs_iget(sb, &fattr); + } -iget_no_retry: if (!inode) { inode = ERR_PTR(rc); goto out; @@ -1469,6 +1498,7 @@ struct inode *cifs_root_iget(struct super_block *sb) out: kfree(path); free_xid(xid); + kfree(fattr.cf_symlink_target); return inode; } diff --git a/fs/smb/client/namespace.c b/fs/smb/client/namespace.c index 3252fe33f7a3..c8f5ed8a69f1 100644 --- a/fs/smb/client/namespace.c +++ b/fs/smb/client/namespace.c @@ -126,9 +126,11 @@ static char *automount_fullpath(struct dentry *dentry, void *page) char *s; spin_lock(&tcon->tc_lock); - if (unlikely(!tcon->origin_fullpath)) { + if (!tcon->origin_fullpath) { spin_unlock(&tcon->tc_lock); - return ERR_PTR(-EREMOTE); + return build_path_from_dentry_optional_prefix(dentry, + page, + true); } spin_unlock(&tcon->tc_lock); @@ -162,7 +164,6 @@ static struct vfsmount *cifs_do_automount(struct path *path) int rc; struct dentry *mntpt = path->dentry; struct fs_context *fc; - struct cifs_sb_info *cifs_sb; void *page = NULL; struct smb3_fs_context *ctx, *cur_ctx; struct smb3_fs_context tmp; @@ -172,17 +173,7 @@ static struct vfsmount *cifs_do_automount(struct path *path) if (IS_ROOT(mntpt)) return ERR_PTR(-ESTALE); - /* - * The MSDFS spec states that paths in DFS referral requests and - * responses must be prefixed by a single '\' character instead of - * the double backslashes usually used in the UNC. This function - * gives us the latter, so we must adjust the result. - */ - cifs_sb = CIFS_SB(mntpt->d_sb); - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_DFS) - return ERR_PTR(-EREMOTE); - - cur_ctx = cifs_sb->ctx; + cur_ctx = CIFS_SB(mntpt->d_sb)->ctx; fc = fs_context_for_submount(path->mnt->mnt_sb->s_type, mntpt); if (IS_ERR(fc)) diff --git a/fs/smb/client/readdir.c b/fs/smb/client/readdir.c index 59bf542d5211..47fc22de8d20 100644 --- a/fs/smb/client/readdir.c +++ b/fs/smb/client/readdir.c @@ -143,6 +143,7 @@ static bool reparse_file_needs_reval(const struct cifs_fattr *fattr) case IO_REPARSE_TAG_DFSR: case IO_REPARSE_TAG_SYMLINK: case IO_REPARSE_TAG_NFS: + case IO_REPARSE_TAG_MOUNT_POINT: case 0: return true; } From patchwork Thu Aug 17 15:34:10 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paulo Alcantara X-Patchwork-Id: 13356729 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 2AB49C3065C for ; Thu, 17 Aug 2023 15:36:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1347286AbjHQPgO (ORCPT ); Thu, 17 Aug 2023 11:36:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39028 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1352650AbjHQPfr (ORCPT ); Thu, 17 Aug 2023 11:35:47 -0400 Received: from mx.manguebit.com (mx.manguebit.com [IPv6:2a01:4f8:1c1e:a2ae::2]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 40BBA30C5 for ; Thu, 17 Aug 2023 08:35:46 -0700 (PDT) From: Paulo Alcantara DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=manguebit.com; s=dkim; t=1692286544; 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=j2C3J9Tk0XRUlrb5yZy7WpiLI7CrUDLjmpi4rmr4xPI=; b=DJPvTKNwtno4B6i0+qgZvFwDmC/63tYPzPXyVX3xHB+cmpbZiYbtLP0+8twelxc4f4Ab1p +5zqeaqvlN2yf8mlt3VbmcJJkWEIQxoKdFERakstm56LcDqQl3Hkyx4D4p6J5uIrJfWsSr iiQv849wxh7ocTExscu4zUdAfSwQpJymWizB94HXQyPMVLH6zVVcIDuZ9CwpZnSWqDPCCM opor6+QrQ3ffnnC4mVM8h87OMzXVQll+opkwudL++usE/IaQWb88Y0Z/irC/tWMbgy+T46 7C7dV0tGqrHFzg4VPMoabO0HbpPgB5nNo09hT1pALiZlalDgVZQCmJ0DbD8ICA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=manguebit.com; s=dkim; t=1692286544; 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=j2C3J9Tk0XRUlrb5yZy7WpiLI7CrUDLjmpi4rmr4xPI=; b=BOQKOaB0r8h3vF1fQhupDzdMI9dTAoecoycy+ntCLhcedmDtbfqMBp+gATeo1RKEQMEunp yCIH5lZougHo811Q+5s4aNkKOTAhn3Xc0mdJ1yj8qG0EFLpFsi/864L3ZSaXKMWnxVeqdb d+AqvrtoCc4Cr5UOA254icag8+AL6ok8ktkHsiWNiq9uHxQOMYt/Wz9hS3mCHoxvqfGNLY OO9FLMBmkMvDUYMJoz+/7yNOmIQ1gSKbhURgCIM5oxyumQQuGoR17sKEHKzZfpUyXZXnIz 5FPU2blrWgocMtvhuNVOCtD+hmpBg09L50YlHxoeZm9lVRlekVPHjtu8mR0wUA== ARC-Authentication-Results: i=1; ORIGINATING; auth=pass smtp.auth=pc@manguebit.com smtp.mailfrom=pc@manguebit.com ARC-Seal: i=1; s=dkim; d=manguebit.com; t=1692286544; a=rsa-sha256; cv=none; b=NIa1vJRTOn+sD2URC6aaccUsSlOCOWvxjvNVPKgnUxBLhJyYdelQRI4UrnxxK/v+5ff699 AO2pTBKOXdQ/HOoP12t0d1glEmbuaEKM2nSZXxtUqtTyEUUOVFyrfc30bdP90hhfremdIo geWToSQEYxEowq4qJHTdBhXu6U6VzEf4zfPppXEAJ7/XkX/n7e9K1oTL02kRNIRzT0Y5U4 6OdlaUfmrG7fsnMe0cbDBsDkHez1uPkR6RFUQpkkk/iOeZIbwqycHCodXLiJ65/TZ2rZ98 4Z0KZUxc4QfmCPh6gSRUW9PPFwku2F3JcI92qZ58SH7mVLItzKyQS1bWq7SLVg== To: smfrench@gmail.com Cc: linux-cifs@vger.kernel.org, Paulo Alcantara , kernel test robot Subject: [PATCH 12/17] smb: client: reduce stack usage in cifs_try_adding_channels() Date: Thu, 17 Aug 2023 12:34:10 -0300 Message-ID: <20230817153416.28083-13-pc@manguebit.com> In-Reply-To: <20230817153416.28083-1-pc@manguebit.com> References: <20230817153416.28083-1-pc@manguebit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Clang warns about exceeded stack frame size fs/smb/client/sess.c:160:5: warning: stack frame size (1368) exceeds limit (1024) in 'cifs_try_adding_channels' [-Wframe-larger-than] It turns out that cifs_ses_add_channel() got inlined into cifs_try_adding_channels() which had a stack-allocated variable @ctx of 624 bytes in size. Fix this by making it heap-allocated. Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202307270640.5ODmPwDl-lkp@intel.com/ Signed-off-by: Paulo Alcantara (SUSE) --- fs/smb/client/sess.c | 68 ++++++++++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 27 deletions(-) diff --git a/fs/smb/client/sess.c b/fs/smb/client/sess.c index c57ca2050b73..5292216d9947 100644 --- a/fs/smb/client/sess.c +++ b/fs/smb/client/sess.c @@ -360,11 +360,11 @@ cifs_ses_add_channel(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses, { struct TCP_Server_Info *chan_server; struct cifs_chan *chan; - struct smb3_fs_context ctx = {NULL}; + struct smb3_fs_context *ctx; static const char unc_fmt[] = "\\%s\\foo"; - char unc[sizeof(unc_fmt)+SERVER_NAME_LEN_WITH_NULL] = {0}; struct sockaddr_in *ipv4 = (struct sockaddr_in *)&iface->sockaddr; struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)&iface->sockaddr; + size_t len; int rc; unsigned int xid = get_xid(); @@ -388,54 +388,64 @@ cifs_ses_add_channel(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses, * the session and server without caring about memory * management. */ + ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + if (!ctx) { + rc = -ENOMEM; + goto out_free_xid; + } /* Always make new connection for now (TODO?) */ - ctx.nosharesock = true; + ctx->nosharesock = true; /* Auth */ - ctx.domainauto = ses->domainAuto; - ctx.domainname = ses->domainName; + ctx->domainauto = ses->domainAuto; + ctx->domainname = ses->domainName; /* no hostname for extra channels */ - ctx.server_hostname = ""; + ctx->server_hostname = ""; - ctx.username = ses->user_name; - ctx.password = ses->password; - ctx.sectype = ses->sectype; - ctx.sign = ses->sign; + ctx->username = ses->user_name; + ctx->password = ses->password; + ctx->sectype = ses->sectype; + ctx->sign = ses->sign; /* UNC and paths */ /* XXX: Use ses->server->hostname? */ - sprintf(unc, unc_fmt, ses->ip_addr); - ctx.UNC = unc; - ctx.prepath = ""; + len = sizeof(unc_fmt) + SERVER_NAME_LEN_WITH_NULL; + ctx->UNC = kzalloc(len, GFP_KERNEL); + if (!ctx->UNC) { + rc = -ENOMEM; + goto out_free_ctx; + } + scnprintf(ctx->UNC, len, unc_fmt, ses->ip_addr); + ctx->prepath = ""; /* Reuse same version as master connection */ - ctx.vals = ses->server->vals; - ctx.ops = ses->server->ops; + ctx->vals = ses->server->vals; + ctx->ops = ses->server->ops; - ctx.noblocksnd = ses->server->noblocksnd; - ctx.noautotune = ses->server->noautotune; - ctx.sockopt_tcp_nodelay = ses->server->tcp_nodelay; - ctx.echo_interval = ses->server->echo_interval / HZ; - ctx.max_credits = ses->server->max_credits; + ctx->noblocksnd = ses->server->noblocksnd; + ctx->noautotune = ses->server->noautotune; + ctx->sockopt_tcp_nodelay = ses->server->tcp_nodelay; + ctx->echo_interval = ses->server->echo_interval / HZ; + ctx->max_credits = ses->server->max_credits; /* * This will be used for encoding/decoding user/domain/pw * during sess setup auth. */ - ctx.local_nls = cifs_sb->local_nls; + ctx->local_nls = cifs_sb->local_nls; /* Use RDMA if possible */ - ctx.rdma = iface->rdma_capable; - memcpy(&ctx.dstaddr, &iface->sockaddr, sizeof(struct sockaddr_storage)); + ctx->rdma = iface->rdma_capable; + memcpy(&ctx->dstaddr, &iface->sockaddr, sizeof(ctx->dstaddr)); /* reuse master con client guid */ - memcpy(&ctx.client_guid, ses->server->client_guid, - SMB2_CLIENT_GUID_SIZE); - ctx.use_client_guid = true; + memcpy(&ctx->client_guid, ses->server->client_guid, + sizeof(ctx->client_guid)); + ctx->use_client_guid = true; - chan_server = cifs_get_tcp_session(&ctx, ses->server); + chan_server = cifs_get_tcp_session(ctx, ses->server); spin_lock(&ses->chan_lock); chan = &ses->chans[ses->chan_count]; @@ -497,6 +507,10 @@ cifs_ses_add_channel(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses, cifs_put_tcp_session(chan->server, 0); } + kfree(ctx->UNC); +out_free_ctx: + kfree(ctx); +out_free_xid: free_xid(xid); return rc; } From patchwork Thu Aug 17 15:34:11 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paulo Alcantara X-Patchwork-Id: 13356727 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 1AA5EC3065D for ; Thu, 17 Aug 2023 15:36:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1352322AbjHQPgP (ORCPT ); Thu, 17 Aug 2023 11:36:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39054 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1352649AbjHQPft (ORCPT ); Thu, 17 Aug 2023 11:35:49 -0400 Received: from mx.manguebit.com (mx.manguebit.com [IPv6:2a01:4f8:1c1e:a2ae::2]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D19A630C5 for ; Thu, 17 Aug 2023 08:35:47 -0700 (PDT) From: Paulo Alcantara DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=manguebit.com; s=dkim; t=1692286546; 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=ZFfThoOQW9o4qr0HUpa3Vb36F6/+z8NMM3fvFNNomg0=; b=LuJLNvMxedYVMA9FMRzZtR2Er4kxg/b2yttmz1XSR4B9zM4RQTP1uwfplZwkeK0hN6ei2k i5G4j88Sg1NguPqudOOy6czfO3JdAscpoGjKYi3dmc4Jit3YPnqurHDSRvUMbBsKogvD+Q QkGb2Lhj/v1ymAz5wN3WYLFxuylBw5o24Osgh2kz+uFBKgWlw5jWaB2ZN7Fe+O1rd3dFuE ESq6tVLkLeyzcld5S+xQQsF5swsAq8tR8xvHnLv9f/bwoebkY3oK6Nnjc8uW9gJJRNEifW awsP1t9NTMcA1ftVOm10fZ+RDJC0H6lZOvqNnIEXBMVxmEJt7N+s0bsxvONzLg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=manguebit.com; s=dkim; t=1692286546; 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=ZFfThoOQW9o4qr0HUpa3Vb36F6/+z8NMM3fvFNNomg0=; b=ImXDQhPsaA/gKy6644vXCdH2+R55pzWPJqghBlXwld/cDcFRC8ENZORaPc2oPkOteqbE/F 8LehhXikktp6e7ESWoArU+KUqCtgLMoTgmNDIgUBIFO+KJxmYYB4BEjzlMvpLaPkxbBKS9 mlUNSNq6B1CoTAA0iZ+2Mu8NtHlcVV3SJTSPj5Ie+qYaCZ4TAf+svqFnhHNGS/8tATQjlV OLv6pIYxDeOJkGXNZJ5jHjAx4GCO+UBJnMTeu6c3lfOvkDuxUpIEyJ3u7A7Qo9QG8wtV1a FbqMgyX8dTzPTBDRRs6Ax3m7ZEaGq5X3GJXMm3fK77dSPDTO7Iik3lzjEML/bA== ARC-Authentication-Results: i=1; ORIGINATING; auth=pass smtp.auth=pc@manguebit.com smtp.mailfrom=pc@manguebit.com ARC-Seal: i=1; s=dkim; d=manguebit.com; t=1692286546; a=rsa-sha256; cv=none; b=JTy51eu5xE+uLL7Yd3g9tXuUirEnEl6g9X4qrr3nX2HUUhiRVURKD+r87FvlXLJYno+j2p vDGDGcgN83PawIYPuWlO1WBIQgCB6x1oY1WXhAWl0rXWnrpHj2sRIb8VJLr+R8i2eBfBhd sezOJ8lU7n7M7NjbyVMBK5kNhKGB9vo5lS5qDwEU2BVGUdh38dW7Aa08q7IOEHy6qkRZZx Tl/YYGI8yJYZqKcckRA6vWvLlT857OWksfnQ9YBaTF6MBxJlT/0AXnFTp8/W8jF1Yyld8M ykUrcvt/ICl7xWM8LfWnInWZ1IdebsLJqMEaIOz0zMDZaAb18fsfBV9uppJ2ZQ== To: smfrench@gmail.com Cc: linux-cifs@vger.kernel.org, Paulo Alcantara Subject: [PATCH 13/17] smb: client: reduce stack usage in cifs_demultiplex_thread() Date: Thu, 17 Aug 2023 12:34:11 -0300 Message-ID: <20230817153416.28083-14-pc@manguebit.com> In-Reply-To: <20230817153416.28083-1-pc@manguebit.com> References: <20230817153416.28083-1-pc@manguebit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Clang warns about exceeded stack frame size fs/smb/client/connect.c:1109:1: warning: stack frame size (1048) exceeds limit (1024) in 'cifs_demultiplex_thread' [-Wframe-larger-than] It turns out that clean_demultiplex_info() got inlined into cifs_demultiplex_thread(), so mark it as noinline_for_stack to save some stack space. Signed-off-by: Paulo Alcantara (SUSE) --- fs/smb/client/connect.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c index b3461d5d0f7d..e19a9c81a5fa 100644 --- a/fs/smb/client/connect.c +++ b/fs/smb/client/connect.c @@ -911,8 +911,8 @@ cifs_enable_signing(struct TCP_Server_Info *server, bool mnt_sign_required) return 0; } - -static void clean_demultiplex_info(struct TCP_Server_Info *server) +static noinline_for_stack void +clean_demultiplex_info(struct TCP_Server_Info *server) { int length; From patchwork Thu Aug 17 15:34:12 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paulo Alcantara X-Patchwork-Id: 13356732 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 7BB72C3DA45 for ; Thu, 17 Aug 2023 15:36:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1352326AbjHQPgP (ORCPT ); Thu, 17 Aug 2023 11:36:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38790 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1353228AbjHQPfu (ORCPT ); Thu, 17 Aug 2023 11:35:50 -0400 Received: from mx.manguebit.com (mx.manguebit.com [167.235.159.17]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 722CC30D8 for ; Thu, 17 Aug 2023 08:35:49 -0700 (PDT) From: Paulo Alcantara DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=manguebit.com; s=dkim; t=1692286548; 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=lTjDRReiGjyTPvMeCsJB3obpBf0aVkmd6MiO7iIGZ0Q=; b=RYaydkuGIhmRJ6ldNmGeKm3HqcyZ40IDuVS6V6vFh0NKmybIZi03I+yHs8HN/yM4HRuvtO ZbyO6HC9NziRCCfOsgF/jpWt//YIm2gVZ5uFVNMQNdJCnVcTWPfoPU+rby+2oxV7G/2wSi HURBDokKcAVKRvKTqP6N19m9B8vCGgpQpeIN0AmWSmAiTz06BF8qcEq6e+7+9v0fqtCBO9 Dh5TaDz/00NzrxAwMOyav3XPUtGfEwxM6yNJbCCypY6JyrN925KbwXaVmq2ubMMNphrF1U KsVz2Cz+5l58nfRb27E0a+xxzX9NDMlCaMMSLD08mTmwjiE/EpaF+42MpvRXxw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=manguebit.com; s=dkim; t=1692286548; 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=lTjDRReiGjyTPvMeCsJB3obpBf0aVkmd6MiO7iIGZ0Q=; b=Im5JqXFihzjQehsQXvhWy6aVzapswBvthu8Mt/AMAAytmoDyMfhgcsGE2jTULbQHW0Sf40 156eVyZvjyQusN/8pdtHT6p01QWfgooh8RG06sJe0pCfiERAK8mfZM4IL81YaXyLDu6nxo hKmKaYlP6kssPA0BxlgIcXptAn4smxr05IfXMtqR3n45no7Me0j4tssbURUjO5gBdx0ecj 9GM5kYo7m8fGduJ08RqcpHBosfZGnHkSAbWb/Nx4L6TswBJZa3iamCuosoZ4XlaL22LoyB GUlA0/sVA6eW0cxv0mPOSUir813/J4DJvTf6YVNhkXLwjrx4PeulASvm9WG1Qw== ARC-Authentication-Results: i=1; ORIGINATING; auth=pass smtp.auth=pc@manguebit.com smtp.mailfrom=pc@manguebit.com ARC-Seal: i=1; s=dkim; d=manguebit.com; t=1692286548; a=rsa-sha256; cv=none; b=EhK/aZU8BEg5tKdlGSvBBCAF1TzsMnabvLwQB78lpgLtAe0BI1jJAieo9iwXERVaaVqsV2 3ckCAidqZBHTcLk4zK7IDXxpmaj1LI5zrLPbq6vKEo5KYtkVgbTw+AENSB6u/5PeYqr7B6 19+9F7muppi9GjpffROX31KTpp9fwwgSdEBlN7IPOVzCSEu1TszvUSEBzogJ74y4CZQVuR hhGaHYznd3AyfpJmebafYUCfPQ4Rw0gbgsrrvw8T0N5RFTXpZnMZ+Md8s4ZCKCf7BJBD5j Az8kG513ngJLMBG/D4+b4ByWph7Qr1RonzzH5O7oWoKwtM735N9DSUdc7i3qLA== To: smfrench@gmail.com Cc: linux-cifs@vger.kernel.org, Paulo Alcantara Subject: [PATCH 14/17] smb: client: reduce stack usage in smb_send_rqst() Date: Thu, 17 Aug 2023 12:34:12 -0300 Message-ID: <20230817153416.28083-15-pc@manguebit.com> In-Reply-To: <20230817153416.28083-1-pc@manguebit.com> References: <20230817153416.28083-1-pc@manguebit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Clang warns about exceeded stack frame size fs/smb/client/transport.c:420:1: warning: stack frame size (1048) exceeds limit (1024) in 'smb_send_rqst' [-Wframe-larger-than] Fix this by allocating a structure that will hold transform header and compound requests. Signed-off-by: Paulo Alcantara (SUSE) --- fs/smb/client/transport.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/fs/smb/client/transport.c b/fs/smb/client/transport.c index f280502a2aee..1b5d9794ed5b 100644 --- a/fs/smb/client/transport.c +++ b/fs/smb/client/transport.c @@ -416,13 +416,19 @@ __smb_send_rqst(struct TCP_Server_Info *server, int num_rqst, return rc; } +struct send_req_vars { + struct smb2_transform_hdr tr_hdr; + struct smb_rqst rqst[MAX_COMPOUND]; + struct kvec iov; +}; + static int smb_send_rqst(struct TCP_Server_Info *server, int num_rqst, struct smb_rqst *rqst, int flags) { - struct kvec iov; - struct smb2_transform_hdr *tr_hdr; - struct smb_rqst cur_rqst[MAX_COMPOUND]; + struct send_req_vars *vars; + struct smb_rqst *cur_rqst; + struct kvec *iov; int rc; if (!(flags & CIFS_TRANSFORM_REQ)) @@ -436,16 +442,15 @@ smb_send_rqst(struct TCP_Server_Info *server, int num_rqst, return -EIO; } - tr_hdr = kzalloc(sizeof(*tr_hdr), GFP_NOFS); - if (!tr_hdr) + vars = kzalloc(sizeof(*vars), GFP_NOFS); + if (!vars) return -ENOMEM; + cur_rqst = vars->rqst; + iov = &vars->iov; - memset(&cur_rqst[0], 0, sizeof(cur_rqst)); - memset(&iov, 0, sizeof(iov)); - - iov.iov_base = tr_hdr; - iov.iov_len = sizeof(*tr_hdr); - cur_rqst[0].rq_iov = &iov; + iov->iov_base = &vars->tr_hdr; + iov->iov_len = sizeof(vars->tr_hdr); + cur_rqst[0].rq_iov = iov; cur_rqst[0].rq_nvec = 1; rc = server->ops->init_transform_rq(server, num_rqst + 1, @@ -456,7 +461,7 @@ smb_send_rqst(struct TCP_Server_Info *server, int num_rqst, rc = __smb_send_rqst(server, num_rqst + 1, &cur_rqst[0]); smb3_free_compound_rqst(num_rqst, &cur_rqst[1]); out: - kfree(tr_hdr); + kfree(vars); return rc; } From patchwork Thu Aug 17 15:34:13 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paulo Alcantara X-Patchwork-Id: 13356733 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 64F98C3DA40 for ; Thu, 17 Aug 2023 15:36:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1352335AbjHQPgP (ORCPT ); Thu, 17 Aug 2023 11:36:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38802 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1353230AbjHQPfw (ORCPT ); Thu, 17 Aug 2023 11:35:52 -0400 Received: from mx.manguebit.com (mx.manguebit.com [167.235.159.17]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 024BA2D6D for ; Thu, 17 Aug 2023 08:35:50 -0700 (PDT) From: Paulo Alcantara DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=manguebit.com; s=dkim; t=1692286549; 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=9COy4bKe5u3yeJNZvanWwWP4V9Cq4YKwxguzpNsinVg=; b=r3ofL8qlM2AndWZ1+V3ndeiFISIZPcnTNjQP5yZG5zU9nLZm0TFlx9+LS8Ei3KjEeU/VXo sHet6Uk/OTa7e5KDC09lRxtGvBISJ75TVWd5om/Wd2LIWEefSrm1cksIXCK9N2+qqcmwkm tRwjb9CauTkMkLQM4E+/3MrvURX3B50fnyViMcgcJ28cV4r215iAH2MkdNRDCuyYS13FbO G/kZ5accKCF67liQJGiX/0qnptmh+QNQoKL7p0rWde3SssF0nVwPfq2KsYG9x5hV5h2S7+ DEdPx22imVAZqJX4p0azTnVJmGqdbOotctDKT4nmocxSM/uQgfWjCuviYwsLLw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=manguebit.com; s=dkim; t=1692286549; 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=9COy4bKe5u3yeJNZvanWwWP4V9Cq4YKwxguzpNsinVg=; b=cfidRzRsWWTRWxKofRJQCG9yelewy1OOXd5tsg2Fq9NQVz84A2cpw0Ekgj32PKTadR15yu szL5Zmyd3gSQgFMy0J9767spxZFlhZV63htlidfCOmAS5zZh+AvCuxR+rQjJMVUYbkNEiQ u+ASB4Mnp6cVjsr3Ac2NvzCHQ+8Cpj7p4Y8EFhBRYDvKzdPa8fdVAKPobk5aNjyQUvo4/m JIjvrZ/02zIXnuAnW6dnV0RYvEqnuamSBm01T4l0G7qbF5cpOfHinoaLMOT3Ulz2/udD1j Zm1ykT7rRDjmzDPKI9HiuRpey2iSX1dtzfKt6nTRpyuhGwJ49CF32paRHAoZgA== ARC-Authentication-Results: i=1; ORIGINATING; auth=pass smtp.auth=pc@manguebit.com smtp.mailfrom=pc@manguebit.com ARC-Seal: i=1; s=dkim; d=manguebit.com; t=1692286549; a=rsa-sha256; cv=none; b=Cr3AIrJ5hdiRfycAJ+6SgNPKOmxCij9DPPnvcCeOTerWGQDWrZoWm8/zxTepzo3fRKa8WT zk1fE6LvIZitRqc12w0u8Dlx9CRKEIpb7TS8qppVpqhjYdr1MFMEcVIgmEWaCYnSUaOeBp r4xCHBGvWq0sLJcViGLg3/dehwxoTuTYCePIOOkeAeo7E2Q4zWHBi6DZKtkPz6Yph4Zu5Q pae3O/XEtK9XUC3tFE2RTWen8x4oYQpM3R5c0eKOHZIR+0GGD0WA+Hq0OUC6/fbCBgz08a RJbkoM/rgm6l6QvfcEnyMoxLXCY3kmLAZXUaa62ANrMO9g3uU9MMZFshXNUIPw== To: smfrench@gmail.com Cc: linux-cifs@vger.kernel.org, Paulo Alcantara Subject: [PATCH 15/17] smb: client: reduce stack usage in smb2_set_ea() Date: Thu, 17 Aug 2023 12:34:13 -0300 Message-ID: <20230817153416.28083-16-pc@manguebit.com> In-Reply-To: <20230817153416.28083-1-pc@manguebit.com> References: <20230817153416.28083-1-pc@manguebit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Clang warns about exceeded stack frame size fs/smb/client/smb2ops.c:1080:1: warning: stack frame size (1432) exceeds limit (1024) in 'smb2_set_ea' [-Wframe-larger-than] Fix this by allocating a structure that will hold most of the large variables. Signed-off-by: Paulo Alcantara (SUSE) --- fs/smb/client/cifsglob.h | 13 ++++++++++ fs/smb/client/smb2inode.c | 21 ++++------------ fs/smb/client/smb2ops.c | 50 ++++++++++++++++----------------------- 3 files changed, 37 insertions(+), 47 deletions(-) diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h index 6d5fa0351dce..1588f98660aa 100644 --- a/fs/smb/client/cifsglob.h +++ b/fs/smb/client/cifsglob.h @@ -2214,4 +2214,17 @@ static inline void cifs_sg_set_buf(struct sg_table *sgtable, } } +struct smb2_compound_vars { + struct cifs_open_parms oparms; + struct kvec rsp_iov[3]; + struct smb_rqst rqst[3]; + struct kvec open_iov[SMB2_CREATE_IOV_SIZE]; + struct kvec qi_iov; + struct kvec io_iov[SMB2_IOCTL_IOV_SIZE]; + struct kvec si_iov[SMB2_SET_INFO_IOV_SIZE]; + struct kvec close_iov; + struct smb2_file_rename_info rename_info; + struct smb2_file_link_info link_info; +}; + #endif /* _CIFS_GLOB_H */ diff --git a/fs/smb/client/smb2inode.c b/fs/smb/client/smb2inode.c index 0999383c0284..b41e2e872b22 100644 --- a/fs/smb/client/smb2inode.c +++ b/fs/smb/client/smb2inode.c @@ -35,19 +35,6 @@ free_set_inf_compound(struct smb_rqst *rqst) SMB2_close_free(&rqst[2]); } - -struct cop_vars { - struct cifs_open_parms oparms; - struct kvec rsp_iov[3]; - struct smb_rqst rqst[3]; - struct kvec open_iov[SMB2_CREATE_IOV_SIZE]; - struct kvec qi_iov[1]; - struct kvec si_iov[SMB2_SET_INFO_IOV_SIZE]; - struct kvec close_iov[1]; - struct smb2_file_rename_info rename_info; - struct smb2_file_link_info link_info; -}; - /* * note: If cfile is passed, the reference to it is dropped here. * So make sure that you do not reuse cfile after return from this func. @@ -63,7 +50,7 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, __u8 **extbuf, size_t *extbuflen, struct kvec *out_iov, int *out_buftype) { - struct cop_vars *vars = NULL; + struct smb2_compound_vars *vars = NULL; struct kvec *rsp_iov; struct smb_rqst *rqst; int rc; @@ -134,7 +121,7 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, /* Operation */ switch (command) { case SMB2_OP_QUERY_INFO: - rqst[num_rqst].rq_iov = &vars->qi_iov[0]; + rqst[num_rqst].rq_iov = &vars->qi_iov; rqst[num_rqst].rq_nvec = 1; if (cfile) @@ -168,7 +155,7 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, full_path); break; case SMB2_OP_POSIX_QUERY_INFO: - rqst[num_rqst].rq_iov = &vars->qi_iov[0]; + rqst[num_rqst].rq_iov = &vars->qi_iov; rqst[num_rqst].rq_nvec = 1; if (cfile) @@ -376,7 +363,7 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, goto after_close; /* Close */ flags |= CIFS_CP_CREATE_CLOSE_OP; - rqst[num_rqst].rq_iov = &vars->close_iov[0]; + rqst[num_rqst].rq_iov = &vars->close_iov; rqst[num_rqst].rq_nvec = 1; rc = SMB2_close_init(tcon, server, &rqst[num_rqst], COMPOUND_FID, diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c index 91c7b7e52a72..d31ea7e7fd84 100644 --- a/fs/smb/client/smb2ops.c +++ b/fs/smb/client/smb2ops.c @@ -1075,31 +1075,28 @@ smb2_query_eas(const unsigned int xid, struct cifs_tcon *tcon, return rc; } - static int smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon, const char *path, const char *ea_name, const void *ea_value, const __u16 ea_value_len, const struct nls_table *nls_codepage, struct cifs_sb_info *cifs_sb) { + struct smb2_compound_vars *vars; struct cifs_ses *ses = tcon->ses; struct TCP_Server_Info *server = cifs_pick_channel(ses); + struct smb_rqst *rqst; + struct kvec *rsp_iov; __le16 *utf16_path = NULL; int ea_name_len = strlen(ea_name); int flags = CIFS_CP_CREATE_CLOSE_OP; int len; - struct smb_rqst rqst[3]; int resp_buftype[3]; - struct kvec rsp_iov[3]; - struct kvec open_iov[SMB2_CREATE_IOV_SIZE]; struct cifs_open_parms oparms; __u8 oplock = SMB2_OPLOCK_LEVEL_NONE; struct cifs_fid fid; - struct kvec si_iov[SMB2_SET_INFO_IOV_SIZE]; unsigned int size[1]; void *data[1]; struct smb2_file_full_ea_info *ea = NULL; - struct kvec close_iov[1]; struct smb2_query_info_rsp *rsp; int rc, used_len = 0; @@ -1113,9 +1110,14 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon, if (!utf16_path) return -ENOMEM; - memset(rqst, 0, sizeof(rqst)); resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER; - memset(rsp_iov, 0, sizeof(rsp_iov)); + vars = kzalloc(sizeof(*vars), GFP_KERNEL); + if (!vars) { + rc = -ENOMEM; + goto out_free_path; + } + rqst = vars->rqst; + rsp_iov = vars->rsp_iov; if (ses->server->ops->query_all_EAs) { if (!ea_value) { @@ -1160,8 +1162,7 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon, } /* Open */ - memset(&open_iov, 0, sizeof(open_iov)); - rqst[0].rq_iov = open_iov; + rqst[0].rq_iov = vars->open_iov; rqst[0].rq_nvec = SMB2_CREATE_IOV_SIZE; oparms = (struct cifs_open_parms) { @@ -1181,8 +1182,7 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon, /* Set Info */ - memset(&si_iov, 0, sizeof(si_iov)); - rqst[1].rq_iov = si_iov; + rqst[1].rq_iov = vars->si_iov; rqst[1].rq_nvec = 1; len = sizeof(*ea) + ea_name_len + ea_value_len + 1; @@ -1210,10 +1210,8 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon, smb2_set_next_command(tcon, &rqst[1]); smb2_set_related(&rqst[1]); - /* Close */ - memset(&close_iov, 0, sizeof(close_iov)); - rqst[2].rq_iov = close_iov; + rqst[2].rq_iov = &vars->close_iov; rqst[2].rq_nvec = 1; rc = SMB2_close_init(tcon, server, &rqst[2], COMPOUND_FID, COMPOUND_FID, false); @@ -1228,13 +1226,15 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon, sea_exit: kfree(ea); - kfree(utf16_path); SMB2_open_free(&rqst[0]); SMB2_set_info_free(&rqst[1]); SMB2_close_free(&rqst[2]); free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base); free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base); free_rsp_buf(resp_buftype[2], rsp_iov[2].iov_base); + kfree(vars); +out_free_path: + kfree(utf16_path); return rc; } #endif @@ -1445,16 +1445,6 @@ SMB2_request_res_key(const unsigned int xid, struct cifs_tcon *tcon, return rc; } -struct iqi_vars { - struct smb_rqst rqst[3]; - struct kvec rsp_iov[3]; - struct kvec open_iov[SMB2_CREATE_IOV_SIZE]; - struct kvec qi_iov[1]; - struct kvec io_iov[SMB2_IOCTL_IOV_SIZE]; - struct kvec si_iov[SMB2_SET_INFO_IOV_SIZE]; - struct kvec close_iov[1]; -}; - static int smb2_ioctl_query_info(const unsigned int xid, struct cifs_tcon *tcon, @@ -1462,7 +1452,7 @@ smb2_ioctl_query_info(const unsigned int xid, __le16 *path, int is_dir, unsigned long p) { - struct iqi_vars *vars; + struct smb2_compound_vars *vars; struct smb_rqst *rqst; struct kvec *rsp_iov; struct cifs_ses *ses = tcon->ses; @@ -1580,7 +1570,7 @@ smb2_ioctl_query_info(const unsigned int xid, rc = -EINVAL; goto free_open_req; } - rqst[1].rq_iov = &vars->si_iov[0]; + rqst[1].rq_iov = vars->si_iov; rqst[1].rq_nvec = 1; /* MS-FSCC 2.4.13 FileEndOfFileInformation */ @@ -1592,7 +1582,7 @@ smb2_ioctl_query_info(const unsigned int xid, SMB2_O_INFO_FILE, 0, data, size); free_req1_func = SMB2_set_info_free; } else if (qi.flags == PASSTHRU_QUERY_INFO) { - rqst[1].rq_iov = &vars->qi_iov[0]; + rqst[1].rq_iov = &vars->qi_iov; rqst[1].rq_nvec = 1; rc = SMB2_query_info_init(tcon, server, @@ -1614,7 +1604,7 @@ smb2_ioctl_query_info(const unsigned int xid, smb2_set_related(&rqst[1]); /* Close */ - rqst[2].rq_iov = &vars->close_iov[0]; + rqst[2].rq_iov = &vars->close_iov; rqst[2].rq_nvec = 1; rc = SMB2_close_init(tcon, server, From patchwork Thu Aug 17 15:34:14 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paulo Alcantara X-Patchwork-Id: 13356730 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 54E32C3DA41 for ; Thu, 17 Aug 2023 15:36:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1352348AbjHQPgQ (ORCPT ); Thu, 17 Aug 2023 11:36:16 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38818 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1353231AbjHQPfx (ORCPT ); Thu, 17 Aug 2023 11:35:53 -0400 Received: from mx.manguebit.com (mx.manguebit.com [IPv6:2a01:4f8:1c1e:a2ae::2]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 86A5F2D6D for ; Thu, 17 Aug 2023 08:35:52 -0700 (PDT) From: Paulo Alcantara DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=manguebit.com; s=dkim; t=1692286551; 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=8NoM8oARTlwjkGW7XsrodOIMPlYfPQYSyAhtX9rK1K4=; b=aM+Mnl6bYzi83AD66h+m+QX9Zg+fj5EBtYJTQtcaNKl67YBTk/PIgw0WEDA5DBuB4lKGlR 0HEpMjZtY9Pc02+ar1204JGYXCakbbOGtnFiDhIjnQgbGgfRYg5DkbxSjF855ogLhsH4Vs 6CTQe1OsJm8smlawPfSHUz4tI2znDUzUVR5bkTiXUcxG3VxFvF2IDY9N6+3zVXhAyyBxPV 2A/dn3YbQrTLkJFJ8ehR0wfkUkQYu4mrfUbss1dcT6kBJcOl7CJ8g/QhVqldQeB3ybBcXj bbFJ6bC3Kvw1FwM6FnuPicFm7HDtSPsi7XqRdKxOHc7reWZel7ENEVtZPu30ig== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=manguebit.com; s=dkim; t=1692286551; 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=8NoM8oARTlwjkGW7XsrodOIMPlYfPQYSyAhtX9rK1K4=; b=BMY2Gsvi3aS0tiaIccAWwB5tuEpVTFD/JqEv/IVvzh01o2427a6X1Qkbf3d54UQNLHen84 +NlCWJa/qTrq1UlbJnRs+A3F1ctht7m6B8Vo0VN6wcBTqUi8JT8LD8mU8NL9gg26uKrXLG 9jnYL3bAnH8Tgi+14qZeA0sln5k4TknVTtCiRhsW6OHFjkDhCv7202tCwVNAyiZ0obR83s jaAsg3Azz8qMPkeAaeCc1MLDSfaEJxac386jr8BTuJ5Ep3mPI286keETc2WA8GfCBqTmuo 3BZSSA/Q8R9IZSCunjGaCdYrSC5WclQf4jykyIEkvVMuYLsgXuK7l0R65m4TDg== ARC-Authentication-Results: i=1; ORIGINATING; auth=pass smtp.auth=pc@manguebit.com smtp.mailfrom=pc@manguebit.com ARC-Seal: i=1; s=dkim; d=manguebit.com; t=1692286551; a=rsa-sha256; cv=none; b=h0hkJwfoC/lMdPzXw6cayiviB+hIeRtoUZ9eZNOK3PwC2Lw6TpxR1WNjJQ+Bg9pcJsNdI5 6W/rN8Pe8Gmf1AwvIg8hmW9omfcufGZC3cvaGDHqsfD0bMwcvUgiaIiZNeIi4SPI2JJD6R BrdxtHnuRbaWFBGYaRRMvcFEBJveb3fMy9NaO3pCedNpFz+eKjTdFaALGsetwllLfUt7GM d3mcL3gaspfzjY3kA+e0h3tNpHr5QJ1qBarroFlalh+0Ykyn36iJoGSCt16RN2c0lo3gFN VLTB/U427PY9lPOSNTrtfXaA2KHc5fLeGigHFqnY8pzFBFnboWIJoDGNag02Qw== To: smfrench@gmail.com Cc: linux-cifs@vger.kernel.org, Paulo Alcantara Subject: [PATCH 16/17] smb: client: reduce stack usage in smb2_query_info_compound() Date: Thu, 17 Aug 2023 12:34:14 -0300 Message-ID: <20230817153416.28083-17-pc@manguebit.com> In-Reply-To: <20230817153416.28083-1-pc@manguebit.com> References: <20230817153416.28083-1-pc@manguebit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Clang warns about exceeded stack frame size fs/smb/client/smb2ops.c:2521:1: warning: stack frame size (1336) exceeds limit (1024) in 'smb2_query_info_compound' [-Wframe-larger-than] Fix this by allocating a structure that will hold most of the large variables. Signed-off-by: Paulo Alcantara (SUSE) --- fs/smb/client/smb2ops.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c index d31ea7e7fd84..015d13d9054d 100644 --- a/fs/smb/client/smb2ops.c +++ b/fs/smb/client/smb2ops.c @@ -2513,15 +2513,13 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon, struct kvec *rsp, int *buftype, struct cifs_sb_info *cifs_sb) { + struct smb2_compound_vars *vars; struct cifs_ses *ses = tcon->ses; struct TCP_Server_Info *server = cifs_pick_channel(ses); int flags = CIFS_CP_CREATE_CLOSE_OP; - struct smb_rqst rqst[3]; + struct smb_rqst *rqst; int resp_buftype[3]; - struct kvec rsp_iov[3]; - struct kvec open_iov[SMB2_CREATE_IOV_SIZE]; - struct kvec qi_iov[1]; - struct kvec close_iov[1]; + struct kvec *rsp_iov; u8 oplock = SMB2_OPLOCK_LEVEL_NONE; struct cifs_open_parms oparms; struct cifs_fid fid; @@ -2538,9 +2536,14 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon, if (smb3_encryption_required(tcon)) flags |= CIFS_TRANSFORM_REQ; - memset(rqst, 0, sizeof(rqst)); resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER; - memset(rsp_iov, 0, sizeof(rsp_iov)); + vars = kzalloc(sizeof(*vars), GFP_KERNEL); + if (!vars) { + rc = -ENOMEM; + goto out_free_path; + } + rqst = vars->rqst; + rsp_iov = vars->rsp_iov; /* * We can only call this for things we know are directories. @@ -2549,8 +2552,7 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon, open_cached_dir(xid, tcon, path, cifs_sb, false, &cfid); /* cfid null if open dir failed */ - memset(&open_iov, 0, sizeof(open_iov)); - rqst[0].rq_iov = open_iov; + rqst[0].rq_iov = vars->open_iov; rqst[0].rq_nvec = SMB2_CREATE_IOV_SIZE; oparms = (struct cifs_open_parms) { @@ -2568,8 +2570,7 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon, goto qic_exit; smb2_set_next_command(tcon, &rqst[0]); - memset(&qi_iov, 0, sizeof(qi_iov)); - rqst[1].rq_iov = qi_iov; + rqst[1].rq_iov = &vars->qi_iov; rqst[1].rq_nvec = 1; if (cfid) { @@ -2596,8 +2597,7 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon, smb2_set_related(&rqst[1]); } - memset(&close_iov, 0, sizeof(close_iov)); - rqst[2].rq_iov = close_iov; + rqst[2].rq_iov = &vars->close_iov; rqst[2].rq_nvec = 1; rc = SMB2_close_init(tcon, server, @@ -2628,7 +2628,6 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon, *buftype = resp_buftype[1]; qic_exit: - kfree(utf16_path); SMB2_open_free(&rqst[0]); SMB2_query_info_free(&rqst[1]); SMB2_close_free(&rqst[2]); @@ -2636,6 +2635,9 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon, free_rsp_buf(resp_buftype[2], rsp_iov[2].iov_base); if (cfid) close_cached_dir(cfid); + kfree(vars); +out_free_path: + kfree(utf16_path); return rc; } From patchwork Thu Aug 17 15:34:15 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paulo Alcantara X-Patchwork-Id: 13356734 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 8C3DBC3DA42 for ; Thu, 17 Aug 2023 15:36:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1352349AbjHQPgQ (ORCPT ); Thu, 17 Aug 2023 11:36:16 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38830 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1353232AbjHQPfz (ORCPT ); Thu, 17 Aug 2023 11:35:55 -0400 Received: from mx.manguebit.com (mx.manguebit.com [IPv6:2a01:4f8:1c1e:a2ae::2]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1E3F02D6D for ; Thu, 17 Aug 2023 08:35:54 -0700 (PDT) From: Paulo Alcantara DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=manguebit.com; s=dkim; t=1692286552; 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=ihyqdEpH/tR/SzrTJNg73Nvb1SClEaj0kTlurvLe2w4=; b=Unx9mNtc1BNpf25Tld8Gunxu7Dx9AfMfOeIRC67YF1TCTi5WlgoKz+UagLDH+ppiQ0Xrey 9Pup4RubVAavXFgQaK7mUL5ELcupyDdIycxEiWhnUEUL9fMDDGxkvyiGh9nXs0llGdLv0c P/481hxmfMX3A2VSE+QrZZzKOIm4S904bO2TGK+Lodhuxh1Its8tUzrn/3c4H3qG+1nzil PhsTUUIwl8bzZYvAhR8AORLUdzAywfmjq8U3NSrWtVdL9uJ+SKgKxLw9vLX+UGN7KRwqaZ uQSdunwiMp86aQBfHKGzU3nb0PaDFI2RE2j2Ot1uGqJHjP3U4NdLH3PT+W3YFw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=manguebit.com; s=dkim; t=1692286552; 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=ihyqdEpH/tR/SzrTJNg73Nvb1SClEaj0kTlurvLe2w4=; b=dxdcvYfEAIlv2KJsg1FwWZAkQrgqUx0wbyLsJ9Nvcw/WvU9d2tVsQxlg7P+Ucc4Hsjzg0k ngjUVEdyZPsXfivWDCDAMWvgURGxUDTSrQ2UWMogI02DGqbrBG0mpNsVdHryptmvT9w6Gp ZO/sGjkSP4nUhAe9JxY2nZbkO7fyd8kOu/FZ6LDRuSBSrJoEy3Hv/qyKsuvA5Gbk+AwoPz BZ7b23lO8UwoooFT2wF19LWZHMoAakoxu/dmc3G81+NOaiw1K357es0RrHqYrBc/HP/l/l VeI7liKIDOiO9E9AVRDN8x+5qSiMGXhgTz6c2V4So+3my+TO8pwFprPO4eA7NQ== ARC-Authentication-Results: i=1; ORIGINATING; auth=pass smtp.auth=pc@manguebit.com smtp.mailfrom=pc@manguebit.com ARC-Seal: i=1; s=dkim; d=manguebit.com; t=1692286552; a=rsa-sha256; cv=none; b=Q6cBPrQ6OPDfY6+AwI5rHTokicEMgEGT/8GxBK+YTs9/4RNFLhWmBrrBTPzXKIUTHGNUo6 9X2pZuLvfgjHFBmX7FrnlnnzucQOi1hI/TltYig+jPHAfp16CCDRZ+bML0crJ03QscwHlR 0S/Zmd0wwfYLrMGu9vkIfk4OXg7FmxsT0b11Wx5idT8KGqwy58RnoK3x00Jcva4JExgPuD aPHA8r4NK8ATfU0ezb6/U31LoVGNLYXbzrTO3ee8+prz02arPVZseE22YRS4gYlSJSazeF uhQgFnc3U+jMArGCvCbNmZmFalrO4smckE3LzqHLcdmgJdYlVmjyKQ5v6VZOIQ== To: smfrench@gmail.com Cc: linux-cifs@vger.kernel.org, Paulo Alcantara Subject: [PATCH 17/17] smb: client: reduce stack usage in smb2_query_reparse_point() Date: Thu, 17 Aug 2023 12:34:15 -0300 Message-ID: <20230817153416.28083-18-pc@manguebit.com> In-Reply-To: <20230817153416.28083-1-pc@manguebit.com> References: <20230817153416.28083-1-pc@manguebit.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Clang warns about exceeded stack frame size fs/smb/client/smb2ops.c:2973:12: warning: stack frame size (1336) exceeds limit (1024) in 'smb2_query_reparse_point' [-Wframe-larger-than] Fix this by allocating a structure that will hold most of the large variables. Signed-off-by: Paulo Alcantara (SUSE) --- fs/smb/client/smb2ops.c | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c index 015d13d9054d..38bc92371560 100644 --- a/fs/smb/client/smb2ops.c +++ b/fs/smb/client/smb2ops.c @@ -2965,6 +2965,7 @@ static int smb2_query_reparse_point(const unsigned int xid, u32 *tag, struct kvec *rsp, int *rsp_buftype) { + struct smb2_compound_vars *vars; int rc; __le16 *utf16_path = NULL; __u8 oplock = SMB2_OPLOCK_LEVEL_NONE; @@ -2972,12 +2973,9 @@ static int smb2_query_reparse_point(const unsigned int xid, struct cifs_fid fid; struct TCP_Server_Info *server = cifs_pick_channel(tcon->ses); int flags = CIFS_CP_CREATE_CLOSE_OP; - struct smb_rqst rqst[3]; + struct smb_rqst *rqst; int resp_buftype[3]; - struct kvec rsp_iov[3]; - struct kvec open_iov[SMB2_CREATE_IOV_SIZE]; - struct kvec io_iov[SMB2_IOCTL_IOV_SIZE]; - struct kvec close_iov[1]; + struct kvec *rsp_iov; struct smb2_ioctl_rsp *ioctl_rsp; struct reparse_data_buffer *reparse_buf; u32 plen; @@ -2987,20 +2985,24 @@ static int smb2_query_reparse_point(const unsigned int xid, if (smb3_encryption_required(tcon)) flags |= CIFS_TRANSFORM_REQ; - memset(rqst, 0, sizeof(rqst)); - resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER; - memset(rsp_iov, 0, sizeof(rsp_iov)); - utf16_path = cifs_convert_path_to_utf16(full_path, cifs_sb); if (!utf16_path) return -ENOMEM; + resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER; + vars = kzalloc(sizeof(*vars), GFP_KERNEL); + if (!vars) { + rc = -ENOMEM; + goto out_free_path; + } + rqst = vars->rqst; + rsp_iov = vars->rsp_iov; + /* * setup smb2open - TODO add optimization to call cifs_get_readable_path * to see if there is a handle already open that we can use */ - memset(&open_iov, 0, sizeof(open_iov)); - rqst[0].rq_iov = open_iov; + rqst[0].rq_iov = vars->open_iov; rqst[0].rq_nvec = SMB2_CREATE_IOV_SIZE; oparms = (struct cifs_open_parms) { @@ -3020,8 +3022,7 @@ static int smb2_query_reparse_point(const unsigned int xid, /* IOCTL */ - memset(&io_iov, 0, sizeof(io_iov)); - rqst[1].rq_iov = io_iov; + rqst[1].rq_iov = vars->io_iov; rqst[1].rq_nvec = SMB2_IOCTL_IOV_SIZE; rc = SMB2_ioctl_init(tcon, server, @@ -3036,10 +3037,8 @@ static int smb2_query_reparse_point(const unsigned int xid, smb2_set_next_command(tcon, &rqst[1]); smb2_set_related(&rqst[1]); - /* Close */ - memset(&close_iov, 0, sizeof(close_iov)); - rqst[2].rq_iov = close_iov; + rqst[2].rq_iov = &vars->close_iov; rqst[2].rq_nvec = 1; rc = SMB2_close_init(tcon, server, @@ -3080,13 +3079,15 @@ static int smb2_query_reparse_point(const unsigned int xid, } query_rp_exit: - kfree(utf16_path); SMB2_open_free(&rqst[0]); SMB2_ioctl_free(&rqst[1]); SMB2_close_free(&rqst[2]); free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base); free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base); free_rsp_buf(resp_buftype[2], rsp_iov[2].iov_base); + kfree(vars); +out_free_path: + kfree(utf16_path); return rc; }