@@ -4099,11 +4099,12 @@ int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon,
40994099 TRANSACTION2_FNEXT_REQ * pSMB = NULL ;
41004100 TRANSACTION2_FNEXT_RSP * pSMBr = NULL ;
41014101 T2_FNEXT_RSP_PARMS * parms ;
4102- char * response_data ;
4103- int rc = 0 ;
4104- int bytes_returned ;
41054102 unsigned int name_len ;
4103+ unsigned int lnoff ;
41064104 __u16 params , byte_count ;
4105+ char * response_data ;
4106+ int bytes_returned ;
4107+ int rc = 0 ;
41074108
41084109 cifs_dbg (FYI , "In FindNext\n" );
41094110
@@ -4148,8 +4149,8 @@ int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon,
41484149 pSMB -> ResumeFileName [name_len ] = 0 ;
41494150 pSMB -> ResumeFileName [name_len + 1 ] = 0 ;
41504151 } else {
4151- rc = - EINVAL ;
4152- goto FNext2_err_exit ;
4152+ cifs_buf_release ( pSMB ) ;
4153+ return - EINVAL ;
41534154 }
41544155 byte_count = params + 1 /* pad */ ;
41554156 pSMB -> TotalParameterCount = cpu_to_le16 (params );
@@ -4160,71 +4161,61 @@ int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon,
41604161 rc = SendReceive (xid , tcon -> ses , (struct smb_hdr * ) pSMB ,
41614162 (struct smb_hdr * ) pSMBr , & bytes_returned , 0 );
41624163 cifs_stats_inc (& tcon -> stats .cifs_stats .num_fnext );
4164+
41634165 if (rc ) {
4166+ cifs_buf_release (pSMB );
41644167 if (rc == - EBADF ) {
41654168 psrch_inf -> endOfSearch = true;
4166- cifs_buf_release (pSMB );
41674169 rc = 0 ; /* search probably was closed at end of search*/
4168- } else
4170+ } else {
41694171 cifs_dbg (FYI , "FindNext returned = %d\n" , rc );
4170- } else { /* decode response */
4171- rc = validate_t2 ((struct smb_t2_rsp * )pSMBr );
4172-
4173- if (rc == 0 ) {
4174- unsigned int lnoff ;
4175-
4176- /* BB fixme add lock for file (srch_info) struct here */
4177- if (pSMBr -> hdr .Flags2 & SMBFLG2_UNICODE )
4178- psrch_inf -> unicode = true;
4179- else
4180- psrch_inf -> unicode = false;
4181- response_data = (char * ) & pSMBr -> hdr .Protocol +
4182- le16_to_cpu (pSMBr -> t2 .ParameterOffset );
4183- parms = (T2_FNEXT_RSP_PARMS * )response_data ;
4184- response_data = (char * )& pSMBr -> hdr .Protocol +
4185- le16_to_cpu (pSMBr -> t2 .DataOffset );
4186- if (psrch_inf -> smallBuf )
4187- cifs_small_buf_release (
4188- psrch_inf -> ntwrk_buf_start );
4189- else
4190- cifs_buf_release (psrch_inf -> ntwrk_buf_start );
4191- psrch_inf -> srch_entries_start = response_data ;
4192- psrch_inf -> ntwrk_buf_start = (char * )pSMB ;
4193- psrch_inf -> smallBuf = false;
4194- if (parms -> EndofSearch )
4195- psrch_inf -> endOfSearch = true;
4196- else
4197- psrch_inf -> endOfSearch = false;
4198- psrch_inf -> entries_in_buffer =
4199- le16_to_cpu (parms -> SearchCount );
4200- psrch_inf -> index_of_last_entry +=
4201- psrch_inf -> entries_in_buffer ;
4202- lnoff = le16_to_cpu (parms -> LastNameOffset );
4203- if (CIFSMaxBufSize < lnoff ) {
4204- cifs_dbg (VFS , "ignoring corrupt resume name\n" );
4205- psrch_inf -> last_entry = NULL ;
4206- return rc ;
4207- } else
4208- psrch_inf -> last_entry =
4209- psrch_inf -> srch_entries_start + lnoff ;
4210-
4211- /* cifs_dbg(FYI, "fnxt2 entries in buf %d index_of_last %d\n",
4212- psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
4213-
4214- /* BB fixme add unlock here */
42154172 }
4173+ return rc ;
4174+ }
42164175
4176+ /* decode response */
4177+ rc = validate_t2 ((struct smb_t2_rsp * )pSMBr );
4178+ if (rc ) {
4179+ cifs_buf_release (pSMB );
4180+ return rc ;
42174181 }
4182+ /* BB fixme add lock for file (srch_info) struct here */
4183+ psrch_inf -> unicode = !!(pSMBr -> hdr .Flags2 & SMBFLG2_UNICODE );
4184+ response_data = (char * )& pSMBr -> hdr .Protocol +
4185+ le16_to_cpu (pSMBr -> t2 .ParameterOffset );
4186+ parms = (T2_FNEXT_RSP_PARMS * )response_data ;
4187+ response_data = (char * )& pSMBr -> hdr .Protocol +
4188+ le16_to_cpu (pSMBr -> t2 .DataOffset );
42184189
4219- /* BB On error, should we leave previous search buf (and count and
4220- last entry fields) intact or free the previous one? */
4190+ if (psrch_inf -> smallBuf )
4191+ cifs_small_buf_release (psrch_inf -> ntwrk_buf_start );
4192+ else
4193+ cifs_buf_release (psrch_inf -> ntwrk_buf_start );
42214194
4222- /* Note: On -EAGAIN error only caller can retry on handle based calls
4223- since file handle passed in no longer valid */
4224- FNext2_err_exit :
4225- if (rc != 0 )
4226- cifs_buf_release (pSMB );
4227- return rc ;
4195+ psrch_inf -> srch_entries_start = response_data ;
4196+ psrch_inf -> ntwrk_buf_start = (char * )pSMB ;
4197+ psrch_inf -> smallBuf = false;
4198+ psrch_inf -> endOfSearch = !!parms -> EndofSearch ;
4199+ psrch_inf -> entries_in_buffer = le16_to_cpu (parms -> SearchCount );
4200+ psrch_inf -> index_of_last_entry += psrch_inf -> entries_in_buffer ;
4201+ lnoff = le16_to_cpu (parms -> LastNameOffset );
4202+ if (CIFSMaxBufSize < lnoff ) {
4203+ cifs_dbg (VFS , "ignoring corrupt resume name\n" );
4204+ psrch_inf -> last_entry = NULL ;
4205+ } else {
4206+ psrch_inf -> last_entry =
4207+ psrch_inf -> srch_entries_start + lnoff ;
4208+ }
4209+ /* BB fixme add unlock here */
4210+
4211+ /*
4212+ * BB: On error, should we leave previous search buf
4213+ * (and count and last entry fields) intact or free the previous one?
4214+ *
4215+ * Note: On -EAGAIN error only caller can retry on handle based calls
4216+ * since file handle passed in no longer valid.
4217+ */
4218+ return 0 ;
42284219}
42294220
42304221int
0 commit comments