@@ -9381,16 +9381,17 @@ static void smb20_oplock_break_ack(struct ksmbd_work *work)
93819381 ksmbd_fd_put (work , fp );
93829382}
93839383
9384- static int check_lease_state ( struct lease * lease , __le32 req_state )
9384+ static bool smb2_lease_state_valid ( __le32 state )
93859385{
9386- if ((lease -> new_state ==
9387- (SMB2_LEASE_READ_CACHING_LE | SMB2_LEASE_HANDLE_CACHING_LE )) &&
9388- !(req_state & SMB2_LEASE_WRITE_CACHING_LE )) {
9389- lease -> new_state = req_state ;
9390- return 0 ;
9391- }
9386+ return !(state & ~(SMB2_LEASE_READ_CACHING_LE |
9387+ SMB2_LEASE_HANDLE_CACHING_LE |
9388+ SMB2_LEASE_WRITE_CACHING_LE ));
9389+ }
93929390
9393- if (lease -> new_state == req_state )
9391+ static int check_lease_state (struct lease * lease , __le32 req_state )
9392+ {
9393+ if (smb2_lease_state_valid (req_state ) &&
9394+ !(req_state & ~lease -> new_state ))
93949395 return 0 ;
93959396
93969397 return 1 ;
@@ -9408,9 +9409,7 @@ static void smb21_lease_break_ack(struct ksmbd_work *work)
94089409 struct smb2_lease_ack * req ;
94099410 struct smb2_lease_ack * rsp ;
94109411 struct oplock_info * opinfo ;
9411- __le32 err = 0 ;
94129412 int ret = 0 ;
9413- unsigned int lease_change_type ;
94149413 __le32 lease_state ;
94159414 struct lease * lease ;
94169415
@@ -9434,80 +9433,23 @@ static void smb21_lease_break_ack(struct ksmbd_work *work)
94349433 goto err_out ;
94359434 }
94369435
9437- if (check_lease_state (lease , req -> LeaseState )) {
9438- rsp -> hdr .Status = STATUS_REQUEST_NOT_ACCEPTED ;
9439- ksmbd_debug (OPLOCK ,
9440- "req lease state: 0x%x, expected state: 0x%x\n" ,
9441- req -> LeaseState , lease -> new_state );
9442- goto err_out ;
9443- }
9444-
94459436 if (!atomic_read (& opinfo -> breaking_cnt )) {
94469437 rsp -> hdr .Status = STATUS_UNSUCCESSFUL ;
94479438 goto err_out ;
94489439 }
94499440
9450- /* check for bad lease state */
9451- if (req -> LeaseState &
9452- (~(SMB2_LEASE_READ_CACHING_LE | SMB2_LEASE_HANDLE_CACHING_LE ))) {
9453- err = STATUS_INVALID_OPLOCK_PROTOCOL ;
9454- if (lease -> state & SMB2_LEASE_WRITE_CACHING_LE )
9455- lease_change_type = OPLOCK_WRITE_TO_NONE ;
9456- else
9457- lease_change_type = OPLOCK_READ_TO_NONE ;
9458- ksmbd_debug (OPLOCK , "handle bad lease state 0x%x -> 0x%x\n" ,
9459- le32_to_cpu (lease -> state ),
9460- le32_to_cpu (req -> LeaseState ));
9461- } else if (lease -> state == SMB2_LEASE_READ_CACHING_LE &&
9462- req -> LeaseState != SMB2_LEASE_NONE_LE ) {
9463- err = STATUS_INVALID_OPLOCK_PROTOCOL ;
9464- lease_change_type = OPLOCK_READ_TO_NONE ;
9465- ksmbd_debug (OPLOCK , "handle bad lease state 0x%x -> 0x%x\n" ,
9466- le32_to_cpu (lease -> state ),
9467- le32_to_cpu (req -> LeaseState ));
9468- } else {
9469- /* valid lease state changes */
9470- err = STATUS_INVALID_DEVICE_STATE ;
9471- if (req -> LeaseState == SMB2_LEASE_NONE_LE ) {
9472- if (lease -> state & SMB2_LEASE_WRITE_CACHING_LE )
9473- lease_change_type = OPLOCK_WRITE_TO_NONE ;
9474- else
9475- lease_change_type = OPLOCK_READ_TO_NONE ;
9476- } else if (req -> LeaseState & SMB2_LEASE_READ_CACHING_LE ) {
9477- if (lease -> state & SMB2_LEASE_WRITE_CACHING_LE )
9478- lease_change_type = OPLOCK_WRITE_TO_READ ;
9479- else
9480- lease_change_type = OPLOCK_READ_HANDLE_TO_READ ;
9481- } else {
9482- lease_change_type = 0 ;
9483- }
9484- }
9485-
9486- switch (lease_change_type ) {
9487- case OPLOCK_WRITE_TO_READ :
9488- ret = opinfo_write_to_read (opinfo );
9489- break ;
9490- case OPLOCK_READ_HANDLE_TO_READ :
9491- ret = opinfo_read_handle_to_read (opinfo );
9492- break ;
9493- case OPLOCK_WRITE_TO_NONE :
9494- ret = opinfo_write_to_none (opinfo );
9495- break ;
9496- case OPLOCK_READ_TO_NONE :
9497- ret = opinfo_read_to_none (opinfo );
9498- break ;
9499- default :
9500- ksmbd_debug (OPLOCK , "unknown lease change 0x%x -> 0x%x\n" ,
9501- le32_to_cpu (lease -> state ),
9502- le32_to_cpu (req -> LeaseState ));
9503- }
9504-
9505- if (ret < 0 ) {
9506- rsp -> hdr .Status = err ;
9441+ if (check_lease_state (lease , req -> LeaseState )) {
9442+ rsp -> hdr .Status = STATUS_REQUEST_NOT_ACCEPTED ;
9443+ ksmbd_debug (OPLOCK ,
9444+ "req lease state: 0x%x, expected state: 0x%x\n" ,
9445+ req -> LeaseState , lease -> new_state );
95079446 goto err_out ;
95089447 }
95099448
9510- lease_state = lease -> state ;
9449+ lease_state = req -> LeaseState ;
9450+ lease -> state = lease_state ;
9451+ lease -> new_state = SMB2_LEASE_NONE_LE ;
9452+ opinfo -> level = smb2_map_lease_to_oplock (lease_state );
95119453
95129454 rsp -> StructureSize = cpu_to_le16 (36 );
95139455 rsp -> Reserved = 0 ;
@@ -9516,16 +9458,20 @@ static void smb21_lease_break_ack(struct ksmbd_work *work)
95169458 rsp -> LeaseState = lease_state ;
95179459 rsp -> LeaseDuration = 0 ;
95189460 ret = ksmbd_iov_pin_rsp (work , rsp , sizeof (struct smb2_lease_ack ));
9519- if (ret ) {
9520- err_out :
9521- smb2_set_err_rsp (work );
9522- }
9461+ if (ret )
9462+ goto err_out ;
95239463
95249464 opinfo -> op_state = OPLOCK_STATE_NONE ;
95259465 wake_up_interruptible_all (& opinfo -> oplock_q );
95269466 atomic_dec (& opinfo -> breaking_cnt );
95279467 wake_up_interruptible_all (& opinfo -> oplock_brk );
95289468 opinfo_put (opinfo );
9469+ return ;
9470+
9471+ err_out :
9472+ smb2_set_err_rsp (work );
9473+ opinfo_put (opinfo );
9474+ return ;
95299475}
95309476
95319477/**
0 commit comments