@ -24,6 +24,7 @@
# include "smb2proto.h"
# include "cifsproto.h"
# include "cifs_debug.h"
# include "cifs_unicode.h"
# include "smb2status.h"
# include "smb2glob.h"
@ -229,7 +230,7 @@ smb2_is_path_accessible(const unsigned int xid, struct cifs_tcon *tcon,
oparms . fid = & fid ;
oparms . reconnect = false ;
rc = SMB2_open ( xid , & oparms , utf16_path , & oplock , NULL ) ;
rc = SMB2_open ( xid , & oparms , utf16_path , & oplock , NULL , NULL ) ;
if ( rc ) {
kfree ( utf16_path ) ;
return rc ;
@ -463,7 +464,7 @@ smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon,
oparms . fid = fid ;
oparms . reconnect = false ;
rc = SMB2_open ( xid , & oparms , utf16_path , & oplock , NULL ) ;
rc = SMB2_open ( xid , & oparms , utf16_path , & oplock , NULL , NULL ) ;
kfree ( utf16_path ) ;
if ( rc ) {
cifs_dbg ( VFS , " open dir failed \n " ) ;
@ -550,7 +551,7 @@ smb2_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
oparms . fid = & fid ;
oparms . reconnect = false ;
rc = SMB2_open ( xid , & oparms , & srch_path , & oplock , NULL ) ;
rc = SMB2_open ( xid , & oparms , & srch_path , & oplock , NULL , NULL ) ;
if ( rc )
return rc ;
buf - > f_type = SMB2_MAGIC_NUMBER ;
@ -596,6 +597,57 @@ smb2_new_lease_key(struct cifs_fid *fid)
get_random_bytes ( fid - > lease_key , SMB2_LEASE_KEY_SIZE ) ;
}
static int
smb2_query_symlink ( const unsigned int xid , struct cifs_tcon * tcon ,
const char * full_path , char * * target_path ,
struct cifs_sb_info * cifs_sb )
{
int rc ;
__le16 * utf16_path ;
__u8 oplock = SMB2_OPLOCK_LEVEL_NONE ;
struct cifs_open_parms oparms ;
struct cifs_fid fid ;
struct smb2_err_rsp * err_buf = NULL ;
struct smb2_symlink_err_rsp * symlink ;
unsigned int sub_len , sub_offset ;
cifs_dbg ( FYI , " %s: path: %s \n " , __func__ , full_path ) ;
utf16_path = cifs_convert_path_to_utf16 ( full_path , cifs_sb ) ;
if ( ! utf16_path )
return - ENOMEM ;
oparms . tcon = tcon ;
oparms . desired_access = FILE_READ_ATTRIBUTES ;
oparms . disposition = FILE_OPEN ;
oparms . create_options = 0 ;
oparms . fid = & fid ;
oparms . reconnect = false ;
rc = SMB2_open ( xid , & oparms , utf16_path , & oplock , NULL , & err_buf ) ;
if ( ! rc | | ! err_buf ) {
kfree ( utf16_path ) ;
return - ENOENT ;
}
/* open must fail on symlink - reset rc */
rc = 0 ;
symlink = ( struct smb2_symlink_err_rsp * ) err_buf - > ErrorData ;
sub_len = le16_to_cpu ( symlink - > SubstituteNameLength ) ;
sub_offset = le16_to_cpu ( symlink - > SubstituteNameOffset ) ;
* target_path = cifs_strndup_from_utf16 (
( char * ) symlink - > PathBuffer + sub_offset ,
sub_len , true , cifs_sb - > local_nls ) ;
if ( ! ( * target_path ) ) {
kfree ( utf16_path ) ;
return - ENOMEM ;
}
convert_delimiter ( * target_path , ' / ' ) ;
cifs_dbg ( FYI , " %s: target path: %s \n " , __func__ , * target_path ) ;
kfree ( utf16_path ) ;
return rc ;
}
struct smb_version_operations smb21_operations = {
. compare_fids = smb2_compare_fids ,
. setup_request = smb2_setup_request ,
@ -638,6 +690,7 @@ struct smb_version_operations smb21_operations = {
. unlink = smb2_unlink ,
. rename = smb2_rename_path ,
. create_hardlink = smb2_create_hardlink ,
. query_symlink = smb2_query_symlink ,
. open = smb2_open_file ,
. set_fid = smb2_set_fid ,
. close = smb2_close_file ,
@ -706,6 +759,7 @@ struct smb_version_operations smb30_operations = {
. unlink = smb2_unlink ,
. rename = smb2_rename_path ,
. create_hardlink = smb2_create_hardlink ,
. query_symlink = smb2_query_symlink ,
. open = smb2_open_file ,
. set_fid = smb2_set_fid ,
. close = smb2_close_file ,