@@ -2599,7 +2599,7 @@ cifs_writev(struct kiocb *iocb, const struct iovec *iov,
25992599 ssize_t err ;
26002600
26012601 err = generic_write_sync (file , iocb -> ki_pos - rc , rc );
2602- if (rc < 0 )
2602+ if (err < 0 )
26032603 rc = err ;
26042604 }
26052605 } else {
@@ -2621,12 +2621,20 @@ cifs_strict_writev(struct kiocb *iocb, const struct iovec *iov,
26212621 struct cifs_tcon * tcon = tlink_tcon (cfile -> tlink );
26222622 ssize_t written ;
26232623
2624+ written = cifs_get_writer (cinode );
2625+ if (written )
2626+ return written ;
2627+
26242628 if (CIFS_CACHE_WRITE (cinode )) {
26252629 if (cap_unix (tcon -> ses ) &&
26262630 (CIFS_UNIX_FCNTL_CAP & le64_to_cpu (tcon -> fsUnixInfo .Capability ))
2627- && ((cifs_sb -> mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL ) == 0 ))
2628- return generic_file_aio_write (iocb , iov , nr_segs , pos );
2629- return cifs_writev (iocb , iov , nr_segs , pos );
2631+ && ((cifs_sb -> mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL ) == 0 )) {
2632+ written = generic_file_aio_write (
2633+ iocb , iov , nr_segs , pos );
2634+ goto out ;
2635+ }
2636+ written = cifs_writev (iocb , iov , nr_segs , pos );
2637+ goto out ;
26302638 }
26312639 /*
26322640 * For non-oplocked files in strict cache mode we need to write the data
@@ -2646,6 +2654,8 @@ cifs_strict_writev(struct kiocb *iocb, const struct iovec *iov,
26462654 inode );
26472655 cinode -> oplock = 0 ;
26482656 }
2657+ out :
2658+ cifs_put_writer (cinode );
26492659 return written ;
26502660}
26512661
@@ -2872,7 +2882,7 @@ ssize_t cifs_user_readv(struct kiocb *iocb, const struct iovec *iov,
28722882 cifs_uncached_readv_complete );
28732883 if (!rdata ) {
28742884 rc = - ENOMEM ;
2875- goto error ;
2885+ break ;
28762886 }
28772887
28782888 rc = cifs_read_allocate_pages (rdata , npages );
@@ -3621,15 +3631,29 @@ static int cifs_launder_page(struct page *page)
36213631 return rc ;
36223632}
36233633
3634+ static int
3635+ cifs_pending_writers_wait (void * unused )
3636+ {
3637+ schedule ();
3638+ return 0 ;
3639+ }
3640+
36243641void cifs_oplock_break (struct work_struct * work )
36253642{
36263643 struct cifsFileInfo * cfile = container_of (work , struct cifsFileInfo ,
36273644 oplock_break );
36283645 struct inode * inode = cfile -> dentry -> d_inode ;
36293646 struct cifsInodeInfo * cinode = CIFS_I (inode );
36303647 struct cifs_tcon * tcon = tlink_tcon (cfile -> tlink );
3648+ struct TCP_Server_Info * server = tcon -> ses -> server ;
36313649 int rc = 0 ;
36323650
3651+ wait_on_bit (& cinode -> flags , CIFS_INODE_PENDING_WRITERS ,
3652+ cifs_pending_writers_wait , TASK_UNINTERRUPTIBLE );
3653+
3654+ server -> ops -> downgrade_oplock (server , cinode ,
3655+ test_bit (CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2 , & cinode -> flags ));
3656+
36333657 if (!CIFS_CACHE_WRITE (cinode ) && CIFS_CACHE_READ (cinode ) &&
36343658 cifs_has_mand_locks (cinode )) {
36353659 cifs_dbg (FYI , "Reset oplock to None for inode=%p due to mand locks\n" ,
@@ -3666,6 +3690,7 @@ void cifs_oplock_break(struct work_struct *work)
36663690 cinode );
36673691 cifs_dbg (FYI , "Oplock release rc = %d\n" , rc );
36683692 }
3693+ cifs_done_oplock_break (cinode );
36693694}
36703695
36713696/*
0 commit comments