From patchwork Fri Mar 18 09:02:07 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Finney X-Patchwork-Id: 647331 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p2L8a66j023923 for ; Mon, 21 Mar 2011 08:36:07 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752358Ab1CUIgG (ORCPT ); Mon, 21 Mar 2011 04:36:06 -0400 Received: from cobija.connexer.com ([66.93.22.232]:40398 "EHLO cobija.connexer.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752345Ab1CUIgF (ORCPT ); Mon, 21 Mar 2011 04:36:05 -0400 X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Mon, 21 Mar 2011 08:36:07 +0000 (UTC) X-Greylist: delayed 395 seconds by postgrey-1.27 at vger.kernel.org; Mon, 21 Mar 2011 04:36:05 EDT Received: by cobija.connexer.com (Postfix, from userid 1000) id 8ECF830009; Mon, 21 Mar 2011 04:29:27 -0400 (EDT) From: Sean Finney To: linux-cifs@vger.kernel.org Date: Fri, 18 Mar 2011 10:02:07 +0100 Subject: [PATCH] Fix Bug#31092: Unable to mount DFS filesystems from Windows 2008 servers Message-Id: <20110321082927.8ECF830009@cobija.connexer.com> Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 8d6c17a..e3a9fd7 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -2825,6 +2825,56 @@ try_mount_again: (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)); remote_path_check: +#ifdef CONFIG_CIFS_DFS_UPCALL + /* + * Perform an unconditional check for whether there are + * DFS referrals for this path (without prefix), to provide + * some limited support for domain DFS referrals on w2k8 + */ + if (referral_walks_count == 0) { + cFYI(1, "Getting referral for: %s", volume_info->UNC); + rc = get_dfs_path(xid, pSesInfo , volume_info->UNC + 1, + cifs_sb->local_nls, &num_referrals, &referrals, + cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); + if (!rc && num_referrals > 0) { + char *fake_devname = NULL; + + full_path = build_unc_path_to_root(volume_info, + cifs_sb); + if (IS_ERR(full_path)) { + rc = PTR_ERR(full_path); + goto mount_fail_check; + } + + if (mount_data != mount_data_global) + kfree(mount_data); + + mount_data = cifs_compose_mount_options( + cifs_sb->mountdata, full_path + 1, + referrals, &fake_devname); + + free_dfs_info_array(referrals, num_referrals); + kfree(fake_devname); + + if (IS_ERR(mount_data)) { + rc = PTR_ERR(mount_data); + mount_data = NULL; + goto mount_fail_check; + } + + if (tcon) + cifs_put_tcon(tcon); + else if (pSesInfo) + cifs_put_smb_ses(pSesInfo); + + cleanup_volume_info(&volume_info); + referral_walks_count++; + FreeXid(xid); + goto try_mount_again; + } + } +#endif + /* check if a whole path (including prepath) is not remote */ if (!rc && cifs_sb->prepathlen && tcon) { /* build_path_to_root works only when we have a valid tcon */