@ -305,67 +305,89 @@ CIFSCouldBeMFSymlink(const struct cifs_fattr *fattr)
}
int
CIFSCheckMFSymlink ( struct cifs_fattr * fattr ,
const unsigned char * path ,
struct cifs_sb_info * cifs_sb , unsigned int xid )
open_query_close_cifs_symlink ( const unsigned char * path , char * pbuf ,
unsigned int * pbytes_read , struct cifs_sb_info * cifs_sb ,
unsigned int xid )
{
int rc ;
int oplock = 0 ;
__u16 netfid = 0 ;
struct tcon_link * tlink ;
struct cifs_tcon * pT con ;
struct cifs_tcon * pt con ;
struct cifs_io_parms io_parms ;
u8 * buf ;
char * pbuf ;
unsigned int bytes_read = 0 ;
int buf_type = CIFS_NO_BUFFER ;
unsigned int link_len = 0 ;
FILE_ALL_INFO file_info ;
if ( ! CIFSCouldBeMFSymlink ( fattr ) )
/* it's not a symlink */
return 0 ;
tlink = cifs_sb_tlink ( cifs_sb ) ;
if ( IS_ERR ( tlink ) )
return PTR_ERR ( tlink ) ;
pT con = tlink_tcon ( tlink ) ;
ptcon = tlink_tcon ( tlink ) ;
rc = CIFSSMBOpen ( xid , pT con , path , FILE_OPEN , GENERIC_READ ,
rc = CIFSSMBOpen ( xid , pt con , path , FILE_OPEN , GENERIC_READ ,
CREATE_NOT_DIR , & netfid , & oplock , & file_info ,
cifs_sb - > local_nls ,
cifs_sb - > mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR ) ;
if ( rc ! = 0 )
goto out ;
if ( rc ! = 0 ) {
cifs_put_tlink ( tlink ) ;
return rc ;
}
if ( file_info . EndOfFile ! = cpu_to_le64 ( CIFS_MF_SYMLINK_FILE_SIZE ) ) {
CIFSSMBClose ( xid , pTcon , netfid ) ;
CIFSSMBClose ( xid , ptcon , netfid ) ;
cifs_put_tlink ( tlink ) ;
/* it's not a symlink */
goto out ;
return rc ;
}
buf = kmalloc ( CIFS_MF_SYMLINK_FILE_SIZE , GFP_KERNEL ) ;
if ( ! buf ) {
rc = - ENOMEM ;
goto out ;
}
pbuf = buf ;
io_parms . netfid = netfid ;
io_parms . pid = current - > tgid ;
io_parms . tcon = pT con ;
io_parms . tcon = ptcon ;
io_parms . offset = 0 ;
io_parms . length = CIFS_MF_SYMLINK_FILE_SIZE ;
rc = CIFSSMBRead ( xid , & io_parms , & bytes_read , & pbuf , & buf_type ) ;
CIFSSMBClose ( xid , pTcon , netfid ) ;
if ( rc ! = 0 ) {
kfree ( buf ) ;
rc = CIFSSMBRead ( xid , & io_parms , pbytes_read , & pbuf , & buf_type ) ;
CIFSSMBClose ( xid , ptcon , netfid ) ;
cifs_put_tlink ( tlink ) ;
return rc ;
}
int
CIFSCheckMFSymlink ( struct cifs_fattr * fattr ,
const unsigned char * path ,
struct cifs_sb_info * cifs_sb , unsigned int xid )
{
int rc = 0 ;
u8 * buf = NULL ;
unsigned int link_len = 0 ;
unsigned int bytes_read = 0 ;
struct cifs_tcon * ptcon ;
if ( ! CIFSCouldBeMFSymlink ( fattr ) )
/* it's not a symlink */
return 0 ;
buf = kmalloc ( CIFS_MF_SYMLINK_FILE_SIZE , GFP_KERNEL ) ;
if ( ! buf ) {
rc = - ENOMEM ;
goto out ;
}
ptcon = tlink_tcon ( cifs_sb_tlink ( cifs_sb ) ) ;
if ( ( ptcon - > ses ) & & ( ptcon - > ses - > server - > ops - > query_mf_symlink ) )
rc = ptcon - > ses - > server - > ops - > query_mf_symlink ( path , buf ,
& bytes_read , cifs_sb , xid ) ;
else
goto out ;
if ( rc ! = 0 )
goto out ;
if ( bytes_read = = 0 ) /* not a symlink */
goto out ;
rc = CIFSParseMFSymlink ( buf , bytes_read , & link_len , NULL ) ;
kfree ( buf ) ;
if ( rc = = - EINVAL ) {
/* it's not a symlink */
rc = 0 ;
@ -381,7 +403,7 @@ CIFSCheckMFSymlink(struct cifs_fattr *fattr,
fattr - > cf_mode | = S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO ;
fattr - > cf_dtype = DT_LNK ;
out :
cifs_put_tlink ( tlink ) ;
kfree ( buf ) ;
return rc ;
}