smb: client: cleanup smb2_query_reparse_point()
authorPaulo Alcantara <pc@manguebit.com>
Sun, 26 Nov 2023 02:55:08 +0000 (23:55 -0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 25 May 2024 14:22:43 +0000 (16:22 +0200)
[ Upstream commit 3ded18a9e9d22a9cba8acad24b77a87851f9c9fa ]

Use smb2_compound_op() with SMB2_OP_GET_REPARSE to get reparse point.

Signed-off-by: Paulo Alcantara (SUSE) <pc@manguebit.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
fs/smb/client/smb2inode.c
fs/smb/client/smb2ops.c
fs/smb/client/smb2proto.h

index 11c1e06ab5417d9d5f4ea9c43a611bbad5481714..1388ce5421a892ae1f0ca02a29adbf70eb7a16b0 100644 (file)
@@ -1054,3 +1054,36 @@ struct inode *smb2_get_reparse_inode(struct cifs_open_info_data *data,
        }
        return rc ? ERR_PTR(rc) : new;
 }
+
+int smb2_query_reparse_point(const unsigned int xid,
+                            struct cifs_tcon *tcon,
+                            struct cifs_sb_info *cifs_sb,
+                            const char *full_path,
+                            u32 *tag, struct kvec *rsp,
+                            int *rsp_buftype)
+{
+       struct cifs_open_info_data data = {};
+       struct cifsFileInfo *cfile;
+       struct kvec in_iov = { .iov_base = &data, .iov_len = sizeof(data), };
+       int rc;
+
+       cifs_dbg(FYI, "%s: path: %s\n", __func__, full_path);
+
+       cifs_get_readable_path(tcon, full_path, &cfile);
+       rc = smb2_compound_op(xid, tcon, cifs_sb, full_path,
+                             FILE_READ_ATTRIBUTES, FILE_OPEN,
+                             OPEN_REPARSE_POINT, ACL_NO_MODE, &in_iov,
+                             &(int){SMB2_OP_GET_REPARSE}, 1, cfile,
+                             NULL, NULL, NULL, NULL);
+       if (rc)
+               goto out;
+
+       *tag = data.reparse.tag;
+       *rsp = data.reparse.io.iov;
+       *rsp_buftype = data.reparse.io.buftype;
+       memset(&data.reparse.io.iov, 0, sizeof(data.reparse.io.iov));
+       data.reparse.io.buftype = CIFS_NO_BUFFER;
+out:
+       cifs_free_open_info(&data);
+       return rc;
+}
index c5957deb1a859e3d7a41956933e46cd21af471fa..a623a720db9e059052cc1a6c0535460a4521c32b 100644 (file)
@@ -2996,145 +2996,6 @@ static int smb2_parse_reparse_point(struct cifs_sb_info *cifs_sb,
        return parse_reparse_point(buf, plen, cifs_sb, true, data);
 }
 
-static int smb2_query_reparse_point(const unsigned int xid,
-                                   struct cifs_tcon *tcon,
-                                   struct cifs_sb_info *cifs_sb,
-                                   const char *full_path,
-                                   u32 *tag, struct kvec *rsp,
-                                   int *rsp_buftype)
-{
-       struct smb2_compound_vars *vars;
-       int rc;
-       __le16 *utf16_path = NULL;
-       __u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
-       struct cifs_open_parms oparms;
-       struct cifs_fid fid;
-       struct TCP_Server_Info *server = cifs_pick_channel(tcon->ses);
-       int flags = CIFS_CP_CREATE_CLOSE_OP;
-       struct smb_rqst *rqst;
-       int resp_buftype[3];
-       struct kvec *rsp_iov;
-       struct smb2_ioctl_rsp *ioctl_rsp;
-       struct reparse_data_buffer *reparse_buf;
-       u32 off, count, len;
-
-       cifs_dbg(FYI, "%s: path: %s\n", __func__, full_path);
-
-       if (smb3_encryption_required(tcon))
-               flags |= CIFS_TRANSFORM_REQ;
-
-       utf16_path = cifs_convert_path_to_utf16(full_path, cifs_sb);
-       if (!utf16_path)
-               return -ENOMEM;
-
-       resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER;
-       vars = kzalloc(sizeof(*vars), GFP_KERNEL);
-       if (!vars) {
-               rc = -ENOMEM;
-               goto out_free_path;
-       }
-       rqst = vars->rqst;
-       rsp_iov = vars->rsp_iov;
-
-       /*
-        * setup smb2open - TODO add optimization to call cifs_get_readable_path
-        * to see if there is a handle already open that we can use
-        */
-       rqst[0].rq_iov = vars->open_iov;
-       rqst[0].rq_nvec = SMB2_CREATE_IOV_SIZE;
-
-       oparms = (struct cifs_open_parms) {
-               .tcon = tcon,
-               .path = full_path,
-               .desired_access = FILE_READ_ATTRIBUTES,
-               .disposition = FILE_OPEN,
-               .create_options = cifs_create_options(cifs_sb, OPEN_REPARSE_POINT),
-               .fid = &fid,
-       };
-
-       rc = SMB2_open_init(tcon, server,
-                           &rqst[0], &oplock, &oparms, utf16_path);
-       if (rc)
-               goto query_rp_exit;
-       smb2_set_next_command(tcon, &rqst[0]);
-
-
-       /* IOCTL */
-       rqst[1].rq_iov = vars->io_iov;
-       rqst[1].rq_nvec = SMB2_IOCTL_IOV_SIZE;
-
-       rc = SMB2_ioctl_init(tcon, server,
-                            &rqst[1], COMPOUND_FID,
-                            COMPOUND_FID, FSCTL_GET_REPARSE_POINT, NULL, 0,
-                            CIFSMaxBufSize -
-                            MAX_SMB2_CREATE_RESPONSE_SIZE -
-                            MAX_SMB2_CLOSE_RESPONSE_SIZE);
-       if (rc)
-               goto query_rp_exit;
-
-       smb2_set_next_command(tcon, &rqst[1]);
-       smb2_set_related(&rqst[1]);
-
-       /* Close */
-       rqst[2].rq_iov = &vars->close_iov;
-       rqst[2].rq_nvec = 1;
-
-       rc = SMB2_close_init(tcon, server,
-                            &rqst[2], COMPOUND_FID, COMPOUND_FID, false);
-       if (rc)
-               goto query_rp_exit;
-
-       smb2_set_related(&rqst[2]);
-
-       rc = compound_send_recv(xid, tcon->ses, server,
-                               flags, 3, rqst,
-                               resp_buftype, rsp_iov);
-
-       ioctl_rsp = rsp_iov[1].iov_base;
-
-       /*
-        * Open was successful and we got an ioctl response.
-        */
-       if (rc == 0) {
-               /* See MS-FSCC 2.3.23 */
-               off = le32_to_cpu(ioctl_rsp->OutputOffset);
-               count = le32_to_cpu(ioctl_rsp->OutputCount);
-               if (check_add_overflow(off, count, &len) ||
-                   len > rsp_iov[1].iov_len) {
-                       cifs_tcon_dbg(VFS, "%s: invalid ioctl: off=%d count=%d\n",
-                                     __func__, off, count);
-                       rc = -EIO;
-                       goto query_rp_exit;
-               }
-
-               reparse_buf = (void *)((u8 *)ioctl_rsp + off);
-               len = sizeof(*reparse_buf);
-               if (count < len ||
-                   count < le16_to_cpu(reparse_buf->ReparseDataLength) + len) {
-                       cifs_tcon_dbg(VFS, "%s: invalid ioctl: off=%d count=%d\n",
-                                     __func__, off, count);
-                       rc = -EIO;
-                       goto query_rp_exit;
-               }
-               *tag = le32_to_cpu(reparse_buf->ReparseTag);
-               *rsp = rsp_iov[1];
-               *rsp_buftype = resp_buftype[1];
-               resp_buftype[1] = CIFS_NO_BUFFER;
-       }
-
- query_rp_exit:
-       SMB2_open_free(&rqst[0]);
-       SMB2_ioctl_free(&rqst[1]);
-       SMB2_close_free(&rqst[2]);
-       free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base);
-       free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base);
-       free_rsp_buf(resp_buftype[2], rsp_iov[2].iov_base);
-       kfree(vars);
-out_free_path:
-       kfree(utf16_path);
-       return rc;
-}
-
 static struct cifs_ntsd *
 get_smb2_acl_by_fid(struct cifs_sb_info *cifs_sb,
                    const struct cifs_fid *cifsfid, u32 *pacllen, u32 info)
index efa2f8fe23449ad7fea349949a3ba3c77c93a9e1..1e20f87a5f584c1e67411205b61b26c6508bd44f 100644 (file)
@@ -62,6 +62,12 @@ struct inode *smb2_get_reparse_inode(struct cifs_open_info_data *data,
                                     struct cifs_tcon *tcon,
                                     const char *full_path,
                                     struct kvec *iov);
+int smb2_query_reparse_point(const unsigned int xid,
+                            struct cifs_tcon *tcon,
+                            struct cifs_sb_info *cifs_sb,
+                            const char *full_path,
+                            u32 *tag, struct kvec *rsp,
+                            int *rsp_buftype);
 int smb2_query_path_info(const unsigned int xid,
                         struct cifs_tcon *tcon,
                         struct cifs_sb_info *cifs_sb,