]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
cifs: Check if server supports reparse points before using them
authorPali Rohár <pali@kernel.org>
Sat, 19 Oct 2024 11:34:18 +0000 (13:34 +0200)
committerSteve French <stfrench@microsoft.com>
Wed, 26 Mar 2025 19:50:37 +0000 (14:50 -0500)
Do not attempt to query or create reparse point when server fs does not
support it. This will prevent creating unusable empty object on the server.

Signed-off-by: Pali Rohár <pali@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/smb/client/cifssmb.c
fs/smb/client/link.c
fs/smb/client/smb2inode.c
fs/smb/client/smb2ops.c

index 4fc9485c5d91a3481c1c67cfd9d7f3763d3b52eb..364ab7573b360223862c8ced91e923917d5a37ed 100644 (file)
@@ -2709,6 +2709,9 @@ int cifs_query_reparse_point(const unsigned int xid,
        if (cap_unix(tcon->ses))
                return -EOPNOTSUPP;
 
+       if (!(le32_to_cpu(tcon->fsAttrInfo.Attributes) & FILE_SUPPORTS_REPARSE_POINTS))
+               return -EOPNOTSUPP;
+
        oparms = (struct cifs_open_parms) {
                .tcon = tcon,
                .cifs_sb = cifs_sb,
index 6e6c09cc5ce7abad829282923730c114de212cd7..a88253668286035676a17e876d2908b7d7c6d10d 100644 (file)
@@ -643,7 +643,8 @@ cifs_symlink(struct mnt_idmap *idmap, struct inode *inode,
        case CIFS_SYMLINK_TYPE_NATIVE:
        case CIFS_SYMLINK_TYPE_NFS:
        case CIFS_SYMLINK_TYPE_WSL:
-               if (server->ops->create_reparse_symlink) {
+               if (server->ops->create_reparse_symlink &&
+                   (le32_to_cpu(pTcon->fsAttrInfo.Attributes) & FILE_SUPPORTS_REPARSE_POINTS)) {
                        rc = server->ops->create_reparse_symlink(xid, inode,
                                                                 direntry,
                                                                 pTcon,
index 826b57a5a2a8d2afb8e5d9b8351248ee855937a1..e9fd3e204a6f4081e9d3b99a1de19e21b2fd3f6c 100644 (file)
@@ -1273,6 +1273,14 @@ struct inode *smb2_get_reparse_inode(struct cifs_open_info_data *data,
        int rc;
        int i;
 
+       /*
+        * If server filesystem does not support reparse points then do not
+        * attempt to create reparse point. This will prevent creating unusable
+        * empty object on the server.
+        */
+       if (!(le32_to_cpu(tcon->fsAttrInfo.Attributes) & FILE_SUPPORTS_REPARSE_POINTS))
+               return ERR_PTR(-EOPNOTSUPP);
+
        oparms = CIFS_OPARMS(cifs_sb, tcon, full_path,
                             SYNCHRONIZE | DELETE |
                             FILE_READ_ATTRIBUTES |
index 6958825431af25e5a646cbebcc367994144829e2..a700e592196149ab92a43bb4e3c9dd3f2284c04c 100644 (file)
@@ -5229,7 +5229,7 @@ static int smb2_make_node(unsigned int xid, struct inode *inode,
                          const char *full_path, umode_t mode, dev_t dev)
 {
        struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
-       int rc;
+       int rc = -EOPNOTSUPP;
 
        /*
         * Check if mounted with mount parm 'sfu' mount parm.
@@ -5240,7 +5240,7 @@ static int smb2_make_node(unsigned int xid, struct inode *inode,
        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
                rc = cifs_sfu_make_node(xid, inode, dentry, tcon,
                                        full_path, mode, dev);
-       } else {
+       } else if (le32_to_cpu(tcon->fsAttrInfo.Attributes) & FILE_SUPPORTS_REPARSE_POINTS) {
                rc = smb2_mknod_reparse(xid, inode, dentry, tcon,
                                        full_path, mode, dev);
        }