diff mbox series

[v1] CIFS: make 'nodfs' mount opt a superblock flag

Message ID 20180921011025.1401-1-aaptel@suse.com
State New
Headers show
Series [v1] CIFS: make 'nodfs' mount opt a superblock flag | expand

Commit Message

Aurélien Aptel Sept. 21, 2018, 1:10 a.m. UTC
tcon->Flags is only used by SMB1 code and changing it is not permanent
(you lose the setting on tcon reconnect).

* Move the setting to superblock flags (per mount-points).
* Make automount callback exit early when flag present
* Make dfs resolving happening in mount syscall exit early if flag present

Signed-off-by: Aurelien Aptel <aaptel@suse.com>
---
 fs/cifs/cifs_dfs_ref.c | 7 ++++++-
 fs/cifs/cifs_fs_sb.h   | 1 +
 fs/cifs/cifsfs.c       | 2 ++
 fs/cifs/connect.c      | 9 +++++----
 4 files changed, 14 insertions(+), 5 deletions(-)

Comments

Pavel Shilovsky Sept. 21, 2018, 10:40 p.m. UTC | #1
чт, 20 сент. 2018 г. в 18:11, Aurelien Aptel <aaptel@suse.com>:
>
> tcon->Flags is only used by SMB1 code and changing it is not permanent
> (you lose the setting on tcon reconnect).
>
> * Move the setting to superblock flags (per mount-points).
> * Make automount callback exit early when flag present
> * Make dfs resolving happening in mount syscall exit early if flag present
>
> Signed-off-by: Aurelien Aptel <aaptel@suse.com>
> ---
>  fs/cifs/cifs_dfs_ref.c | 7 ++++++-
>  fs/cifs/cifs_fs_sb.h   | 1 +
>  fs/cifs/cifsfs.c       | 2 ++
>  fs/cifs/connect.c      | 9 +++++----
>  4 files changed, 14 insertions(+), 5 deletions(-)
>
> diff --git a/fs/cifs/cifs_dfs_ref.c b/fs/cifs/cifs_dfs_ref.c
> index 6b61df117fd4..b97c74efd04a 100644
> --- a/fs/cifs/cifs_dfs_ref.c
> +++ b/fs/cifs/cifs_dfs_ref.c
> @@ -304,12 +304,17 @@ static struct vfsmount *cifs_dfs_do_automount(struct dentry *mntpt)
>          */
>         mnt = ERR_PTR(-ENOMEM);
>
> +       cifs_sb = CIFS_SB(mntpt->d_sb);
> +       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_DFS) {
> +               mnt = ERR_PTR(-EREMOTE);
> +               goto cdda_exit;
> +       }
> +
>         /* always use tree name prefix */
>         full_path = build_path_from_dentry_optional_prefix(mntpt, true);
>         if (full_path == NULL)
>                 goto cdda_exit;
>
> -       cifs_sb = CIFS_SB(mntpt->d_sb);
>         tlink = cifs_sb_tlink(cifs_sb);
>         if (IS_ERR(tlink)) {
>                 mnt = ERR_CAST(tlink);
> diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
> index 9731d0d891e7..63d7530f2e1d 100644
> --- a/fs/cifs/cifs_fs_sb.h
> +++ b/fs/cifs/cifs_fs_sb.h
> @@ -51,6 +51,7 @@
>                                               */
>  #define CIFS_MOUNT_UID_FROM_ACL 0x2000000 /* try to get UID via special SID */
>  #define CIFS_MOUNT_NO_HANDLE_CACHE 0x4000000 /* disable caching dir handles */
> +#define CIFS_MOUNT_NO_DFS 0x8000000 /* disable DFS resolving */
>
>  struct cifs_sb_info {
>         struct rb_root tlink_tree;
> diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
> index ba0054604f85..d2f9bc48ffac 100644
> --- a/fs/cifs/cifsfs.c
> +++ b/fs/cifs/cifsfs.c
> @@ -500,6 +500,8 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
>                 seq_puts(s, ",unix");
>         else
>                 seq_puts(s, ",nounix");
> +       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_DFS)
> +               seq_puts(s, ",nodfs");
>         if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
>                 seq_puts(s, ",posixpaths");
>         if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)
> diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
> index 7e6dd7873961..5ca1a5760398 100644
> --- a/fs/cifs/connect.c
> +++ b/fs/cifs/connect.c
> @@ -3087,10 +3087,6 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info)
>         if (rc)
>                 goto out_fail;
>
> -       if (volume_info->nodfs) {
> -               tcon->Flags &= ~SMB_SHARE_IS_IN_DFS;
> -               cifs_dbg(FYI, "DFS disabled (%d)\n", tcon->Flags);
> -       }
>         tcon->use_persistent = false;
>         /* check if SMB2 or later, CIFS does not support persistent handles */
>         if (volume_info->persistent) {
> @@ -3665,6 +3661,8 @@ int cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
>         cifs_sb->actimeo = pvolume_info->actimeo;
>         cifs_sb->local_nls = pvolume_info->local_nls;
>
> +       if (pvolume_info->nodfs)
> +               cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_DFS;
>         if (pvolume_info->noperm)
>                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
>         if (pvolume_info->setuids)
> @@ -3821,6 +3819,9 @@ expand_dfs_referral(const unsigned int xid, struct cifs_ses *ses,
>         struct dfs_info3_param *referrals = NULL;
>         char *full_path = NULL, *ref_path = NULL, *mdata = NULL;
>
> +       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_DFS)
> +               return -EREMOTE;
> +
>         full_path = build_unc_path_to_root(volume_info, cifs_sb);
>         if (IS_ERR(full_path))
>                 return PTR_ERR(full_path);
> --
> 2.13.7
>

Looks good.

Acked-by: Pavel Shilovsky <pshilov@microsoft.com>

--
Best regards,
Pavel Shilovsky
Steve French Sept. 22, 2018, 3 a.m. UTC | #2
Merged into cifs-2.6.git for-next
On Thu, Sep 20, 2018 at 8:10 PM Aurelien Aptel <aaptel@suse.com> wrote:
>
> tcon->Flags is only used by SMB1 code and changing it is not permanent
> (you lose the setting on tcon reconnect).
>
> * Move the setting to superblock flags (per mount-points).
> * Make automount callback exit early when flag present
> * Make dfs resolving happening in mount syscall exit early if flag present
>
> Signed-off-by: Aurelien Aptel <aaptel@suse.com>
> ---
>  fs/cifs/cifs_dfs_ref.c | 7 ++++++-
>  fs/cifs/cifs_fs_sb.h   | 1 +
>  fs/cifs/cifsfs.c       | 2 ++
>  fs/cifs/connect.c      | 9 +++++----
>  4 files changed, 14 insertions(+), 5 deletions(-)
>
> diff --git a/fs/cifs/cifs_dfs_ref.c b/fs/cifs/cifs_dfs_ref.c
> index 6b61df117fd4..b97c74efd04a 100644
> --- a/fs/cifs/cifs_dfs_ref.c
> +++ b/fs/cifs/cifs_dfs_ref.c
> @@ -304,12 +304,17 @@ static struct vfsmount *cifs_dfs_do_automount(struct dentry *mntpt)
>          */
>         mnt = ERR_PTR(-ENOMEM);
>
> +       cifs_sb = CIFS_SB(mntpt->d_sb);
> +       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_DFS) {
> +               mnt = ERR_PTR(-EREMOTE);
> +               goto cdda_exit;
> +       }
> +
>         /* always use tree name prefix */
>         full_path = build_path_from_dentry_optional_prefix(mntpt, true);
>         if (full_path == NULL)
>                 goto cdda_exit;
>
> -       cifs_sb = CIFS_SB(mntpt->d_sb);
>         tlink = cifs_sb_tlink(cifs_sb);
>         if (IS_ERR(tlink)) {
>                 mnt = ERR_CAST(tlink);
> diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
> index 9731d0d891e7..63d7530f2e1d 100644
> --- a/fs/cifs/cifs_fs_sb.h
> +++ b/fs/cifs/cifs_fs_sb.h
> @@ -51,6 +51,7 @@
>                                               */
>  #define CIFS_MOUNT_UID_FROM_ACL 0x2000000 /* try to get UID via special SID */
>  #define CIFS_MOUNT_NO_HANDLE_CACHE 0x4000000 /* disable caching dir handles */
> +#define CIFS_MOUNT_NO_DFS 0x8000000 /* disable DFS resolving */
>
>  struct cifs_sb_info {
>         struct rb_root tlink_tree;
> diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
> index ba0054604f85..d2f9bc48ffac 100644
> --- a/fs/cifs/cifsfs.c
> +++ b/fs/cifs/cifsfs.c
> @@ -500,6 +500,8 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
>                 seq_puts(s, ",unix");
>         else
>                 seq_puts(s, ",nounix");
> +       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_DFS)
> +               seq_puts(s, ",nodfs");
>         if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
>                 seq_puts(s, ",posixpaths");
>         if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)
> diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
> index 7e6dd7873961..5ca1a5760398 100644
> --- a/fs/cifs/connect.c
> +++ b/fs/cifs/connect.c
> @@ -3087,10 +3087,6 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info)
>         if (rc)
>                 goto out_fail;
>
> -       if (volume_info->nodfs) {
> -               tcon->Flags &= ~SMB_SHARE_IS_IN_DFS;
> -               cifs_dbg(FYI, "DFS disabled (%d)\n", tcon->Flags);
> -       }
>         tcon->use_persistent = false;
>         /* check if SMB2 or later, CIFS does not support persistent handles */
>         if (volume_info->persistent) {
> @@ -3665,6 +3661,8 @@ int cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
>         cifs_sb->actimeo = pvolume_info->actimeo;
>         cifs_sb->local_nls = pvolume_info->local_nls;
>
> +       if (pvolume_info->nodfs)
> +               cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_DFS;
>         if (pvolume_info->noperm)
>                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
>         if (pvolume_info->setuids)
> @@ -3821,6 +3819,9 @@ expand_dfs_referral(const unsigned int xid, struct cifs_ses *ses,
>         struct dfs_info3_param *referrals = NULL;
>         char *full_path = NULL, *ref_path = NULL, *mdata = NULL;
>
> +       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_DFS)
> +               return -EREMOTE;
> +
>         full_path = build_unc_path_to_root(volume_info, cifs_sb);
>         if (IS_ERR(full_path))
>                 return PTR_ERR(full_path);
> --
> 2.13.7
>
diff mbox series

Patch

diff --git a/fs/cifs/cifs_dfs_ref.c b/fs/cifs/cifs_dfs_ref.c
index 6b61df117fd4..b97c74efd04a 100644
--- a/fs/cifs/cifs_dfs_ref.c
+++ b/fs/cifs/cifs_dfs_ref.c
@@ -304,12 +304,17 @@  static struct vfsmount *cifs_dfs_do_automount(struct dentry *mntpt)
 	 */
 	mnt = ERR_PTR(-ENOMEM);
 
+	cifs_sb = CIFS_SB(mntpt->d_sb);
+	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_DFS) {
+		mnt = ERR_PTR(-EREMOTE);
+		goto cdda_exit;
+	}
+
 	/* always use tree name prefix */
 	full_path = build_path_from_dentry_optional_prefix(mntpt, true);
 	if (full_path == NULL)
 		goto cdda_exit;
 
-	cifs_sb = CIFS_SB(mntpt->d_sb);
 	tlink = cifs_sb_tlink(cifs_sb);
 	if (IS_ERR(tlink)) {
 		mnt = ERR_CAST(tlink);
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
index 9731d0d891e7..63d7530f2e1d 100644
--- a/fs/cifs/cifs_fs_sb.h
+++ b/fs/cifs/cifs_fs_sb.h
@@ -51,6 +51,7 @@ 
 					      */
 #define CIFS_MOUNT_UID_FROM_ACL 0x2000000 /* try to get UID via special SID */
 #define CIFS_MOUNT_NO_HANDLE_CACHE 0x4000000 /* disable caching dir handles */
+#define CIFS_MOUNT_NO_DFS 0x8000000 /* disable DFS resolving */
 
 struct cifs_sb_info {
 	struct rb_root tlink_tree;
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index ba0054604f85..d2f9bc48ffac 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -500,6 +500,8 @@  cifs_show_options(struct seq_file *s, struct dentry *root)
 		seq_puts(s, ",unix");
 	else
 		seq_puts(s, ",nounix");
+	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_DFS)
+		seq_puts(s, ",nodfs");
 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
 		seq_puts(s, ",posixpaths");
 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 7e6dd7873961..5ca1a5760398 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -3087,10 +3087,6 @@  cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info)
 	if (rc)
 		goto out_fail;
 
-	if (volume_info->nodfs) {
-		tcon->Flags &= ~SMB_SHARE_IS_IN_DFS;
-		cifs_dbg(FYI, "DFS disabled (%d)\n", tcon->Flags);
-	}
 	tcon->use_persistent = false;
 	/* check if SMB2 or later, CIFS does not support persistent handles */
 	if (volume_info->persistent) {
@@ -3665,6 +3661,8 @@  int cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
 	cifs_sb->actimeo = pvolume_info->actimeo;
 	cifs_sb->local_nls = pvolume_info->local_nls;
 
+	if (pvolume_info->nodfs)
+		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_DFS;
 	if (pvolume_info->noperm)
 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
 	if (pvolume_info->setuids)
@@ -3821,6 +3819,9 @@  expand_dfs_referral(const unsigned int xid, struct cifs_ses *ses,
 	struct dfs_info3_param *referrals = NULL;
 	char *full_path = NULL, *ref_path = NULL, *mdata = NULL;
 
+	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_DFS)
+		return -EREMOTE;
+
 	full_path = build_unc_path_to_root(volume_info, cifs_sb);
 	if (IS_ERR(full_path))
 		return PTR_ERR(full_path);