@@ -2948,153 +2948,30 @@ parse_reparse_point(struct reparse_data_buffer *buf,
29482948 }
29492949}
29502950
2951- static int
2952- smb2_query_symlink (const unsigned int xid , struct cifs_tcon * tcon ,
2953- struct cifs_sb_info * cifs_sb , const char * full_path ,
2954- char * * target_path , bool is_reparse_point )
2951+ static int smb2_query_symlink (const unsigned int xid ,
2952+ struct cifs_tcon * tcon ,
2953+ struct cifs_sb_info * cifs_sb ,
2954+ const char * full_path ,
2955+ char * * target_path ,
2956+ struct kvec * rsp_iov )
29552957{
2956- int rc ;
2957- __le16 * utf16_path = NULL ;
2958- __u8 oplock = SMB2_OPLOCK_LEVEL_NONE ;
2959- struct cifs_open_parms oparms ;
2960- struct cifs_fid fid ;
2961- struct kvec err_iov = {NULL , 0 };
2962- struct TCP_Server_Info * server = cifs_pick_channel (tcon -> ses );
2963- int flags = CIFS_CP_CREATE_CLOSE_OP ;
2964- struct smb_rqst rqst [3 ];
2965- int resp_buftype [3 ];
2966- struct kvec rsp_iov [3 ];
2967- struct kvec open_iov [SMB2_CREATE_IOV_SIZE ];
2968- struct kvec io_iov [SMB2_IOCTL_IOV_SIZE ];
2969- struct kvec close_iov [1 ];
2970- struct smb2_create_rsp * create_rsp ;
2971- struct smb2_ioctl_rsp * ioctl_rsp ;
2972- struct reparse_data_buffer * reparse_buf ;
2973- int create_options = is_reparse_point ? OPEN_REPARSE_POINT : 0 ;
2974- u32 plen ;
2958+ struct reparse_data_buffer * buf ;
2959+ struct smb2_ioctl_rsp * io = rsp_iov -> iov_base ;
2960+ u32 plen = le32_to_cpu (io -> OutputCount );
29752961
29762962 cifs_dbg (FYI , "%s: path: %s\n" , __func__ , full_path );
29772963
2978- * target_path = NULL ;
2979-
2980- if (smb3_encryption_required (tcon ))
2981- flags |= CIFS_TRANSFORM_REQ ;
2982-
2983- memset (rqst , 0 , sizeof (rqst ));
2984- resp_buftype [0 ] = resp_buftype [1 ] = resp_buftype [2 ] = CIFS_NO_BUFFER ;
2985- memset (rsp_iov , 0 , sizeof (rsp_iov ));
2986-
2987- utf16_path = cifs_convert_path_to_utf16 (full_path , cifs_sb );
2988- if (!utf16_path )
2989- return - ENOMEM ;
2990-
2991- /* Open */
2992- memset (& open_iov , 0 , sizeof (open_iov ));
2993- rqst [0 ].rq_iov = open_iov ;
2994- rqst [0 ].rq_nvec = SMB2_CREATE_IOV_SIZE ;
2995-
2996- oparms = (struct cifs_open_parms ) {
2997- .tcon = tcon ,
2998- .path = full_path ,
2999- .desired_access = FILE_READ_ATTRIBUTES ,
3000- .disposition = FILE_OPEN ,
3001- .create_options = cifs_create_options (cifs_sb , create_options ),
3002- .fid = & fid ,
3003- };
3004-
3005- rc = SMB2_open_init (tcon , server ,
3006- & rqst [0 ], & oplock , & oparms , utf16_path );
3007- if (rc )
3008- goto querty_exit ;
3009- smb2_set_next_command (tcon , & rqst [0 ]);
3010-
3011-
3012- /* IOCTL */
3013- memset (& io_iov , 0 , sizeof (io_iov ));
3014- rqst [1 ].rq_iov = io_iov ;
3015- rqst [1 ].rq_nvec = SMB2_IOCTL_IOV_SIZE ;
3016-
3017- rc = SMB2_ioctl_init (tcon , server ,
3018- & rqst [1 ], fid .persistent_fid ,
3019- fid .volatile_fid , FSCTL_GET_REPARSE_POINT , NULL , 0 ,
3020- CIFSMaxBufSize -
3021- MAX_SMB2_CREATE_RESPONSE_SIZE -
3022- MAX_SMB2_CLOSE_RESPONSE_SIZE );
3023- if (rc )
3024- goto querty_exit ;
3025-
3026- smb2_set_next_command (tcon , & rqst [1 ]);
3027- smb2_set_related (& rqst [1 ]);
3028-
3029-
3030- /* Close */
3031- memset (& close_iov , 0 , sizeof (close_iov ));
3032- rqst [2 ].rq_iov = close_iov ;
3033- rqst [2 ].rq_nvec = 1 ;
3034-
3035- rc = SMB2_close_init (tcon , server ,
3036- & rqst [2 ], COMPOUND_FID , COMPOUND_FID , false);
3037- if (rc )
3038- goto querty_exit ;
3039-
3040- smb2_set_related (& rqst [2 ]);
3041-
3042- rc = compound_send_recv (xid , tcon -> ses , server ,
3043- flags , 3 , rqst ,
3044- resp_buftype , rsp_iov );
3045-
3046- create_rsp = rsp_iov [0 ].iov_base ;
3047- if (create_rsp && create_rsp -> hdr .Status )
3048- err_iov = rsp_iov [0 ];
3049- ioctl_rsp = rsp_iov [1 ].iov_base ;
3050-
3051- /*
3052- * Open was successful and we got an ioctl response.
3053- */
3054- if ((rc == 0 ) && (is_reparse_point )) {
3055- /* See MS-FSCC 2.3.23 */
3056-
3057- reparse_buf = (struct reparse_data_buffer * )
3058- ((char * )ioctl_rsp +
3059- le32_to_cpu (ioctl_rsp -> OutputOffset ));
3060- plen = le32_to_cpu (ioctl_rsp -> OutputCount );
3061-
3062- if (plen + le32_to_cpu (ioctl_rsp -> OutputOffset ) >
3063- rsp_iov [1 ].iov_len ) {
3064- cifs_tcon_dbg (VFS , "srv returned invalid ioctl len: %d\n" ,
3065- plen );
3066- rc = - EIO ;
3067- goto querty_exit ;
3068- }
3069-
3070- rc = parse_reparse_point (reparse_buf , plen , target_path ,
3071- cifs_sb );
3072- goto querty_exit ;
3073- }
3074-
3075- if (!rc || !err_iov .iov_base ) {
3076- rc = - ENOENT ;
3077- goto querty_exit ;
3078- }
3079-
3080- rc = smb2_parse_symlink_response (cifs_sb , & err_iov , target_path );
3081-
3082- querty_exit :
3083- cifs_dbg (FYI , "query symlink rc %d\n" , rc );
3084- kfree (utf16_path );
3085- SMB2_open_free (& rqst [0 ]);
3086- SMB2_ioctl_free (& rqst [1 ]);
3087- SMB2_close_free (& rqst [2 ]);
3088- free_rsp_buf (resp_buftype [0 ], rsp_iov [0 ].iov_base );
3089- free_rsp_buf (resp_buftype [1 ], rsp_iov [1 ].iov_base );
3090- free_rsp_buf (resp_buftype [2 ], rsp_iov [2 ].iov_base );
3091- return rc ;
2964+ buf = (struct reparse_data_buffer * )((u8 * )io +
2965+ le32_to_cpu (io -> OutputOffset ));
2966+ return parse_reparse_point (buf , plen , target_path , cifs_sb );
30922967}
30932968
3094- int
3095- smb2_query_reparse_tag (const unsigned int xid , struct cifs_tcon * tcon ,
3096- struct cifs_sb_info * cifs_sb , const char * full_path ,
3097- __u32 * tag )
2969+ static int smb2_query_reparse_point (const unsigned int xid ,
2970+ struct cifs_tcon * tcon ,
2971+ struct cifs_sb_info * cifs_sb ,
2972+ const char * full_path ,
2973+ u32 * tag , struct kvec * rsp ,
2974+ int * rsp_buftype )
30982975{
30992976 int rc ;
31002977 __le16 * utf16_path = NULL ;
@@ -3205,6 +3082,9 @@ smb2_query_reparse_tag(const unsigned int xid, struct cifs_tcon *tcon,
32053082 goto query_rp_exit ;
32063083 }
32073084 * tag = le32_to_cpu (reparse_buf -> ReparseTag );
3085+ * rsp = rsp_iov [1 ];
3086+ * rsp_buftype = resp_buftype [1 ];
3087+ resp_buftype [1 ] = CIFS_NO_BUFFER ;
32083088 }
32093089
32103090 query_rp_exit :
@@ -5503,7 +5383,7 @@ struct smb_version_operations smb30_operations = {
55035383 .echo = SMB2_echo ,
55045384 .query_path_info = smb2_query_path_info ,
55055385 /* WSL tags introduced long after smb2.1, enable for SMB3, 3.11 only */
5506- .query_reparse_tag = smb2_query_reparse_tag ,
5386+ .query_reparse_point = smb2_query_reparse_point ,
55075387 .get_srv_inum = smb2_get_srv_inum ,
55085388 .query_file_info = smb2_query_file_info ,
55095389 .set_path_size = smb2_set_path_size ,
@@ -5616,7 +5496,7 @@ struct smb_version_operations smb311_operations = {
56165496 .can_echo = smb2_can_echo ,
56175497 .echo = SMB2_echo ,
56185498 .query_path_info = smb2_query_path_info ,
5619- .query_reparse_tag = smb2_query_reparse_tag ,
5499+ .query_reparse_point = smb2_query_reparse_point ,
56205500 .get_srv_inum = smb2_get_srv_inum ,
56215501 .query_file_info = smb2_query_file_info ,
56225502 .set_path_size = smb2_set_path_size ,
0 commit comments