summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPali Rohár <pali@kernel.org>2024-09-18 00:28:25 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2025-03-22 12:54:19 -0700
commit7ece63c977c11979007c2b65b3cc4bb6eabc1aab (patch)
tree9b895a8e6ff5113ab97fa4d9893d8601fe1c1ea7
parent317fb015fe58d32e3c6f10f194edde2cab1100ce (diff)
cifs: Treat unhandled directory name surrogate reparse points as mount directory nodes
[ 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@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r--fs/smb/client/inode.c13
-rw-r--r--fs/smb/common/smbfsctl.h3
2 files changed, 16 insertions, 0 deletions
diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c
index a3f0835e12be..97151715d1a4 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 4b379e84c46b..3253a18ecb5c 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