From patchwork Wed Sep 7 14:53:23 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sachin Prabhu X-Patchwork-Id: 9319425 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id C5146601C0 for ; Wed, 7 Sep 2016 14:53:38 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B5766293C3 for ; Wed, 7 Sep 2016 14:53:38 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A9CD5293C6; Wed, 7 Sep 2016 14:53:38 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 18406293C3 for ; Wed, 7 Sep 2016 14:53:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757854AbcIGOxb (ORCPT ); Wed, 7 Sep 2016 10:53:31 -0400 Received: from mx1.redhat.com ([209.132.183.28]:49618 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757853AbcIGOx2 (ORCPT ); Wed, 7 Sep 2016 10:53:28 -0400 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 075FEC056791 for ; Wed, 7 Sep 2016 14:53:28 +0000 (UTC) Received: from sprabhu-lp.redhat.com (ovpn-116-87.ams2.redhat.com [10.36.116.87]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u87ErOli005288 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 7 Sep 2016 10:53:26 -0400 From: Sachin Prabhu To: linux-cifs Subject: [PATCH] cifs_get_root shouldn't use path with tree name Date: Wed, 7 Sep 2016 15:53:23 +0100 Message-Id: <1473260003-5271-1-git-send-email-sprabhu@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Wed, 07 Sep 2016 14:53:28 +0000 (UTC) Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP When a server returns the optional flag SMB_SHARE_IS_IN_DFS in response to a tree connect, cifs_build_path_to_root() will return a pathname which includes the tree name. This causes problems with cifs_get_root() which separates each component and does a lookup for each component of the path. We encountered a problem with dfs shares hosted by a Netapp. when connecting to nodes pointed to by the DFS share. The tree connect for these nodes return SMB_SHARE_IS_IN_DFS even after the DFS node is resolved and the node returned doesn't contain a DFS share. Other servers(tested with MS Win2012 R2) do not and hence do not face this problem. A workaround for Netapp servers is to mount with the nodfs flag. The return flag results in cifs_build_path_to_root() using the tree name in building the path which is then split into its components and individual lookup done for each component in cifs_get_root(). The first component of the path in this case is the hostname which results in object not found errors. We have tested this patch both on our internal test servers as well as the user's own servers and can confirm that it fixes the problem. Signed-off-by: Sachin Prabhu Reported-by: Pierguido Lambri Reviewed-by: Jeff Layton --- fs/cifs/cifsfs.c | 2 +- fs/cifs/cifsproto.h | 3 ++- fs/cifs/connect.c | 3 ++- fs/cifs/dir.c | 4 ++-- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 6bbec5e..b6f57dd 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -610,7 +610,7 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb) char sep; full_path = cifs_build_path_to_root(vol, cifs_sb, - cifs_sb_master_tcon(cifs_sb)); + cifs_sb_master_tcon(cifs_sb), 0); if (full_path == NULL) return ERR_PTR(-ENOMEM); diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 1243bd3..52c307b 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -63,7 +63,8 @@ extern void exit_cifs_spnego(void); extern char *build_path_from_dentry(struct dentry *); extern char *cifs_build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb, - struct cifs_tcon *tcon); + struct cifs_tcon *tcon, + int add_treename); extern char *build_wildcard_path_from_dentry(struct dentry *direntry); extern char *cifs_compose_mount_options(const char *sb_mountdata, const char *fullpath, const struct dfs_info3_param *ref, diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 9878943..afca9ee 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -3649,7 +3649,8 @@ remote_path_check: /* * cifs_build_path_to_root works only when we have a valid tcon */ - full_path = cifs_build_path_to_root(volume_info, cifs_sb, tcon); + full_path = cifs_build_path_to_root(volume_info, cifs_sb, tcon, + tcon->Flags & SMB_SHARE_IS_IN_DFS); if (full_path == NULL) { rc = -ENOMEM; goto mount_fail_check; diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 4716c54..4c0c62c 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c @@ -47,7 +47,7 @@ renew_parental_timestamps(struct dentry *direntry) char * cifs_build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb, - struct cifs_tcon *tcon) + struct cifs_tcon *tcon, int add_treename) { int pplen = vol->prepath ? strlen(vol->prepath) + 1 : 0; int dfsplen; @@ -59,7 +59,7 @@ cifs_build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb, return full_path; } - if (tcon->Flags & SMB_SHARE_IS_IN_DFS) + if (add_treename) dfsplen = strnlen(tcon->treeName, MAX_TREE_SIZE + 1); else dfsplen = 0;