Skip to content

Commit c114609

Browse files
pcacjrgregkh
authored andcommitted
smb: client: set symlink type as native for POSIX mounts
commit a967e75 upstream. SMB3.1.1 POSIX mounts require symlinks to be created natively with IO_REPARSE_TAG_SYMLINK reparse point. Cc: linux-cifs@vger.kernel.org Cc: Ralph Boehme <slow@samba.org> Cc: David Howells <dhowells@redhat.com> Cc: <stable@vger.kernel.org> Reported-by: Matthew Richardson <m.richardson@ed.ac.uk> Closes: https://marc.info/?i=1124e7cd-6a46-40a6-9f44-b7664a66654b@ed.ac.uk Signed-off-by: Paulo Alcantara (Red Hat) <pc@manguebit.org> Signed-off-by: Steve French <stfrench@microsoft.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent b4755b0 commit c114609

5 files changed

Lines changed: 22 additions & 29 deletions

File tree

fs/smb/client/cifsfs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -724,7 +724,7 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
724724
else
725725
seq_puts(s, ",nativesocket");
726726
seq_show_option(s, "symlink",
727-
cifs_symlink_type_str(get_cifs_symlink_type(cifs_sb)));
727+
cifs_symlink_type_str(cifs_symlink_type(cifs_sb)));
728728

729729
seq_printf(s, ",rsize=%u", cifs_sb->ctx->rsize);
730730
seq_printf(s, ",wsize=%u", cifs_sb->ctx->wsize);

fs/smb/client/fs_context.c

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1851,24 +1851,6 @@ static int smb3_fs_context_parse_param(struct fs_context *fc,
18511851
return -EINVAL;
18521852
}
18531853

1854-
enum cifs_symlink_type get_cifs_symlink_type(struct cifs_sb_info *cifs_sb)
1855-
{
1856-
if (cifs_sb->ctx->symlink_type == CIFS_SYMLINK_TYPE_DEFAULT) {
1857-
if (cifs_sb->ctx->mfsymlinks)
1858-
return CIFS_SYMLINK_TYPE_MFSYMLINKS;
1859-
else if (cifs_sb->ctx->sfu_emul)
1860-
return CIFS_SYMLINK_TYPE_SFU;
1861-
else if (cifs_sb->ctx->linux_ext && !cifs_sb->ctx->no_linux_ext)
1862-
return CIFS_SYMLINK_TYPE_UNIX;
1863-
else if (cifs_sb->ctx->reparse_type != CIFS_REPARSE_TYPE_NONE)
1864-
return CIFS_SYMLINK_TYPE_NATIVE;
1865-
else
1866-
return CIFS_SYMLINK_TYPE_NONE;
1867-
} else {
1868-
return cifs_sb->ctx->symlink_type;
1869-
}
1870-
}
1871-
18721854
int smb3_init_fs_context(struct fs_context *fc)
18731855
{
18741856
struct smb3_fs_context *ctx;

fs/smb/client/fs_context.h

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,23 @@ struct smb3_fs_context {
341341

342342
extern const struct fs_parameter_spec smb3_fs_parameters[];
343343

344-
extern enum cifs_symlink_type get_cifs_symlink_type(struct cifs_sb_info *cifs_sb);
344+
static inline enum cifs_symlink_type cifs_symlink_type(struct cifs_sb_info *cifs_sb)
345+
{
346+
bool posix = cifs_sb_master_tcon(cifs_sb)->posix_extensions;
347+
348+
if (cifs_sb->ctx->symlink_type != CIFS_SYMLINK_TYPE_DEFAULT)
349+
return cifs_sb->ctx->symlink_type;
350+
351+
if (cifs_sb->ctx->mfsymlinks)
352+
return CIFS_SYMLINK_TYPE_MFSYMLINKS;
353+
else if (cifs_sb->ctx->sfu_emul)
354+
return CIFS_SYMLINK_TYPE_SFU;
355+
else if (cifs_sb->ctx->linux_ext && !cifs_sb->ctx->no_linux_ext)
356+
return posix ? CIFS_SYMLINK_TYPE_NATIVE : CIFS_SYMLINK_TYPE_UNIX;
357+
else if (cifs_sb->ctx->reparse_type != CIFS_REPARSE_TYPE_NONE)
358+
return CIFS_SYMLINK_TYPE_NATIVE;
359+
return CIFS_SYMLINK_TYPE_NONE;
360+
}
345361

346362
extern int smb3_init_fs_context(struct fs_context *fc);
347363
extern void smb3_cleanup_fs_context_contents(struct smb3_fs_context *ctx);

fs/smb/client/link.c

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -606,14 +606,7 @@ cifs_symlink(struct mnt_idmap *idmap, struct inode *inode,
606606

607607
/* BB what if DFS and this volume is on different share? BB */
608608
rc = -EOPNOTSUPP;
609-
switch (get_cifs_symlink_type(cifs_sb)) {
610-
case CIFS_SYMLINK_TYPE_DEFAULT:
611-
/* should not happen, get_cifs_symlink_type() resolves the default */
612-
break;
613-
614-
case CIFS_SYMLINK_TYPE_NONE:
615-
break;
616-
609+
switch (cifs_symlink_type(cifs_sb)) {
617610
case CIFS_SYMLINK_TYPE_UNIX:
618611
#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
619612
if (pTcon->unix_ext) {
@@ -653,6 +646,8 @@ cifs_symlink(struct mnt_idmap *idmap, struct inode *inode,
653646
goto symlink_exit;
654647
}
655648
break;
649+
default:
650+
break;
656651
}
657652

658653
if (rc == 0) {

fs/smb/client/reparse.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ int smb2_create_reparse_symlink(const unsigned int xid, struct inode *inode,
3838
struct dentry *dentry, struct cifs_tcon *tcon,
3939
const char *full_path, const char *symname)
4040
{
41-
switch (get_cifs_symlink_type(CIFS_SB(inode->i_sb))) {
41+
switch (cifs_symlink_type(CIFS_SB(inode->i_sb))) {
4242
case CIFS_SYMLINK_TYPE_NATIVE:
4343
return create_native_symlink(xid, inode, dentry, tcon, full_path, symname);
4444
case CIFS_SYMLINK_TYPE_NFS:

0 commit comments

Comments
 (0)