Skip to content

Commit 5c6664c

Browse files
committed
smb: client: set symlink type as native for POSIX mounts
JIRA: https://issues.redhat.com/browse/RHEL-109507 commit a967e75 Author: Paulo Alcantara <pc@manguebit.org> Date: Thu Jul 31 20:46:41 2025 -0300 smb: client: set symlink type as native for POSIX mounts 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: Paulo Alcantara <paalcant@redhat.com>
1 parent 2abb63e commit 5c6664c

File tree

5 files changed

+22
-29
lines changed

5 files changed

+22
-29
lines changed

fs/smb/client/cifsfs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -717,7 +717,7 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
717717
else
718718
seq_puts(s, ",nativesocket");
719719
seq_show_option(s, "symlink",
720-
cifs_symlink_type_str(get_cifs_symlink_type(cifs_sb)));
720+
cifs_symlink_type_str(cifs_symlink_type(cifs_sb)));
721721

722722
seq_printf(s, ",rsize=%u", cifs_sb->ctx->rsize);
723723
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
@@ -1844,24 +1844,6 @@ static int smb3_fs_context_parse_param(struct fs_context *fc,
18441844
return -EINVAL;
18451845
}
18461846

1847-
enum cifs_symlink_type get_cifs_symlink_type(struct cifs_sb_info *cifs_sb)
1848-
{
1849-
if (cifs_sb->ctx->symlink_type == CIFS_SYMLINK_TYPE_DEFAULT) {
1850-
if (cifs_sb->ctx->mfsymlinks)
1851-
return CIFS_SYMLINK_TYPE_MFSYMLINKS;
1852-
else if (cifs_sb->ctx->sfu_emul)
1853-
return CIFS_SYMLINK_TYPE_SFU;
1854-
else if (cifs_sb->ctx->linux_ext && !cifs_sb->ctx->no_linux_ext)
1855-
return CIFS_SYMLINK_TYPE_UNIX;
1856-
else if (cifs_sb->ctx->reparse_type != CIFS_REPARSE_TYPE_NONE)
1857-
return CIFS_SYMLINK_TYPE_NATIVE;
1858-
else
1859-
return CIFS_SYMLINK_TYPE_NONE;
1860-
} else {
1861-
return cifs_sb->ctx->symlink_type;
1862-
}
1863-
}
1864-
18651847
int smb3_init_fs_context(struct fs_context *fc)
18661848
{
18671849
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
@@ -605,14 +605,7 @@ cifs_symlink(struct mnt_idmap *idmap, struct inode *inode,
605605

606606
/* BB what if DFS and this volume is on different share? BB */
607607
rc = -EOPNOTSUPP;
608-
switch (get_cifs_symlink_type(cifs_sb)) {
609-
case CIFS_SYMLINK_TYPE_DEFAULT:
610-
/* should not happen, get_cifs_symlink_type() resolves the default */
611-
break;
612-
613-
case CIFS_SYMLINK_TYPE_NONE:
614-
break;
615-
608+
switch (cifs_symlink_type(cifs_sb)) {
616609
case CIFS_SYMLINK_TYPE_UNIX:
617610
#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
618611
if (pTcon->unix_ext) {
@@ -648,6 +641,8 @@ cifs_symlink(struct mnt_idmap *idmap, struct inode *inode,
648641
goto symlink_exit;
649642
}
650643
break;
644+
default:
645+
break;
651646
}
652647

653648
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 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)