On Mon, 25 Nov 2013 17:09:55 +0000
Sachin Prabhu <[email protected]> wrote:
> When using posix extensions, dfs shares in the dfs root show up as
> symlinks resulting in userland tools such as 'ls' calling readlink() on
> these shares. Since these are dfs shares, readlink fails with -EREMOTE.
>
> With added support for dfs shares on readlink when using unix
> extensions, we call GET_DFS_REFERRAL to obtain the DFS referral and
> return the first node returned.
>
> The dfs share in the dfs root is now displayed in the following manner.
> $ ls -l /mnt
> total 0
> lrwxrwxrwx. 1 root root 19 Nov 6 09:47 test -> \vm140-31\test
>
nit: I know that DFS referrals are prefixed with a single backslash,
but it might look more like a UNC with a double backslash prefix:
lrwxrwxrwx. 1 root root 19 Nov 6 09:47 test -> \\vm140-31\test
...but I don't feel too strongly about it.
> Red Hat BZ: 1020715
>
> Signed-off-by: Sachin Prabhu <[email protected]>
> ---
> fs/cifs/smb1ops.c | 34 +++++++++++++++++++++++++++++++++-
> 1 file changed, 33 insertions(+), 1 deletion(-)
>
> diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c
> index 2d822dd..abd2cc9 100644
> --- a/fs/cifs/smb1ops.c
> +++ b/fs/cifs/smb1ops.c
> @@ -908,6 +908,33 @@ cifs_mand_lock(const unsigned int xid, struct
> cifsFileInfo *cfile, __u64 offset,
> }
>
> static int
> +cifs_unix_dfs_readlink(const unsigned int xid, struct cifs_tcon *tcon,
> + const unsigned char *searchName, char **symlinkinfo,
> + const struct nls_table *nls_codepage)
> +{
> +#ifdef CONFIG_CIFS_DFS_UPCALL
> + int rc;
> + unsigned int num_referrals = 0;
> + struct dfs_info3_param *referrals = NULL;
> +
> + rc = get_dfs_path(xid, tcon->ses, searchName, nls_codepage,
> + &num_referrals, &referrals, 0);
> +
> + if (!rc && num_referrals > 0) {
> + *symlinkinfo = kstrndup(referrals->node_name,
> + strlen(referrals->node_name),
> + GFP_KERNEL);
> + if (!*symlinkinfo)
> + rc = -ENOMEM;
> + free_dfs_info_array(referrals, num_referrals);
> + }
> + return rc;
> +#else /* No DFS support */
> + return -EREMOTE;
> +#endif
> +}
> +
> +static int
> cifs_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
> const char *full_path, char **target_path,
> struct cifs_sb_info *cifs_sb)
> @@ -920,8 +947,13 @@ cifs_query_symlink(const unsigned int xid, struct
> cifs_tcon *tcon,
>
> /* Check for unix extensions */
> if (cap_unix(tcon->ses)) {
> - rc = CIFSSMBUnixQuerySymLink(xid, tcon, full_path, &target_path,
> + rc = CIFSSMBUnixQuerySymLink(xid, tcon, full_path, target_path,
> cifs_sb->local_nls);
> + if (rc == -EREMOTE)
> + rc = cifs_unix_dfs_readlink(xid, tcon, full_path,
> + target_path,
> + cifs_sb->local_nls);
> +
> goto out;
> }
>
Either way, this is a marked improvement:
Reviewed-by: Jeff Layton <[email protected]>
--
To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html