This patch depends on cad3fc0a4c8cef07b07ceddc137f582267577250 ("cifs: Throw -EOPNOTSUPP error on unsupported reparse point type from parse_reparse_point()". Please ensure that this dependency is included. On Monday 24 February 2025 06:17:56 Sasha Levin wrote: > From: Pali Rohár <pali@xxxxxxxxxx> > > [ Upstream commit b587fd128660d48cd2122f870f720ff8e2b4abb3 ] > > If the reparse point was not handled (indicated by the -EOPNOTSUPP from > ops->parse_reparse_point() call) but reparse tag is of type name surrogate > directory type, then treat is as a new mount point. > > Name surrogate reparse point represents another named entity in the system. > > From SMB client point of view, this another entity is resolved on the SMB > server, and server serves its content automatically. Therefore from Linux > client point of view, this name surrogate reparse point of directory type > crosses mount point. > > Signed-off-by: Pali Rohár <pali@xxxxxxxxxx> > Signed-off-by: Steve French <stfrench@xxxxxxxxxxxxx> > Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx> > --- > fs/smb/client/inode.c | 13 +++++++++++++ > fs/smb/common/smbfsctl.h | 3 +++ > 2 files changed, 16 insertions(+) > > diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c > index fafc07e38663c..295afb73fcdd6 100644 > --- a/fs/smb/client/inode.c > +++ b/fs/smb/client/inode.c > @@ -1193,6 +1193,19 @@ static int reparse_info_to_fattr(struct cifs_open_info_data *data, > rc = server->ops->parse_reparse_point(cifs_sb, > full_path, > iov, data); > + /* > + * If the reparse point was not handled but it is the > + * name surrogate which points to directory, then treat > + * is as a new mount point. Name surrogate reparse point > + * represents another named entity in the system. > + */ > + if (rc == -EOPNOTSUPP && > + IS_REPARSE_TAG_NAME_SURROGATE(data->reparse.tag) && > + (le32_to_cpu(data->fi.Attributes) & ATTR_DIRECTORY)) { > + rc = 0; > + cifs_create_junction_fattr(fattr, sb); > + goto out; > + } > } > break; > } > diff --git a/fs/smb/common/smbfsctl.h b/fs/smb/common/smbfsctl.h > index 4b379e84c46b9..3253a18ecb5cb 100644 > --- a/fs/smb/common/smbfsctl.h > +++ b/fs/smb/common/smbfsctl.h > @@ -159,6 +159,9 @@ > #define IO_REPARSE_TAG_LX_CHR 0x80000025 > #define IO_REPARSE_TAG_LX_BLK 0x80000026 > > +/* If Name Surrogate Bit is set, the file or directory represents another named entity in the system. */ > +#define IS_REPARSE_TAG_NAME_SURROGATE(tag) (!!((tag) & 0x20000000)) > + > /* fsctl flags */ > /* If Flags is set to this value, the request is an FSCTL not ioctl request */ > #define SMB2_0_IOCTL_IS_FSCTL 0x00000001 > -- > 2.39.5 >