@@ -305,6 +305,7 @@ cifs_new_fileinfo(struct cifs_fid *fid, struct file *file,
305
305
cfile -> tlink = cifs_get_tlink (tlink );
306
306
INIT_WORK (& cfile -> oplock_break , cifs_oplock_break );
307
307
mutex_init (& cfile -> fh_mutex );
308
+ spin_lock_init (& cfile -> file_info_lock );
308
309
309
310
cifs_sb_active (inode -> i_sb );
310
311
@@ -317,7 +318,7 @@ cifs_new_fileinfo(struct cifs_fid *fid, struct file *file,
317
318
oplock = 0 ;
318
319
}
319
320
320
- spin_lock (& cifs_file_list_lock );
321
+ spin_lock (& tcon -> open_file_lock );
321
322
if (fid -> pending_open -> oplock != CIFS_OPLOCK_NO_CHANGE && oplock )
322
323
oplock = fid -> pending_open -> oplock ;
323
324
list_del (& fid -> pending_open -> olist );
@@ -326,12 +327,13 @@ cifs_new_fileinfo(struct cifs_fid *fid, struct file *file,
326
327
server -> ops -> set_fid (cfile , fid , oplock );
327
328
328
329
list_add (& cfile -> tlist , & tcon -> openFileList );
330
+
329
331
/* if readable file instance put first in list*/
330
332
if (file -> f_mode & FMODE_READ )
331
333
list_add (& cfile -> flist , & cinode -> openFileList );
332
334
else
333
335
list_add_tail (& cfile -> flist , & cinode -> openFileList );
334
- spin_unlock (& cifs_file_list_lock );
336
+ spin_unlock (& tcon -> open_file_lock );
335
337
336
338
if (fid -> purge_cache )
337
339
cifs_zap_mapping (inode );
@@ -343,16 +345,16 @@ cifs_new_fileinfo(struct cifs_fid *fid, struct file *file,
343
345
struct cifsFileInfo *
344
346
cifsFileInfo_get (struct cifsFileInfo * cifs_file )
345
347
{
346
- spin_lock (& cifs_file_list_lock );
348
+ spin_lock (& cifs_file -> file_info_lock );
347
349
cifsFileInfo_get_locked (cifs_file );
348
- spin_unlock (& cifs_file_list_lock );
350
+ spin_unlock (& cifs_file -> file_info_lock );
349
351
return cifs_file ;
350
352
}
351
353
352
354
/*
353
355
* Release a reference on the file private data. This may involve closing
354
356
* the filehandle out on the server. Must be called without holding
355
- * cifs_file_list_lock .
357
+ * tcon->open_file_lock and cifs_file->file_info_lock .
356
358
*/
357
359
void cifsFileInfo_put (struct cifsFileInfo * cifs_file )
358
360
{
@@ -367,11 +369,15 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
367
369
struct cifs_pending_open open ;
368
370
bool oplock_break_cancelled ;
369
371
370
- spin_lock (& cifs_file_list_lock );
372
+ spin_lock (& tcon -> open_file_lock );
373
+
374
+ spin_lock (& cifs_file -> file_info_lock );
371
375
if (-- cifs_file -> count > 0 ) {
372
- spin_unlock (& cifs_file_list_lock );
376
+ spin_unlock (& cifs_file -> file_info_lock );
377
+ spin_unlock (& tcon -> open_file_lock );
373
378
return ;
374
379
}
380
+ spin_unlock (& cifs_file -> file_info_lock );
375
381
376
382
if (server -> ops -> get_lease_key )
377
383
server -> ops -> get_lease_key (inode , & fid );
@@ -395,7 +401,8 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
395
401
set_bit (CIFS_INO_INVALID_MAPPING , & cifsi -> flags );
396
402
cifs_set_oplock_level (cifsi , 0 );
397
403
}
398
- spin_unlock (& cifs_file_list_lock );
404
+
405
+ spin_unlock (& tcon -> open_file_lock );
399
406
400
407
oplock_break_cancelled = cancel_work_sync (& cifs_file -> oplock_break );
401
408
@@ -772,10 +779,10 @@ int cifs_closedir(struct inode *inode, struct file *file)
772
779
server = tcon -> ses -> server ;
773
780
774
781
cifs_dbg (FYI , "Freeing private data in close dir\n" );
775
- spin_lock (& cifs_file_list_lock );
782
+ spin_lock (& cfile -> file_info_lock );
776
783
if (server -> ops -> dir_needs_close (cfile )) {
777
784
cfile -> invalidHandle = true;
778
- spin_unlock (& cifs_file_list_lock );
785
+ spin_unlock (& cfile -> file_info_lock );
779
786
if (server -> ops -> close_dir )
780
787
rc = server -> ops -> close_dir (xid , tcon , & cfile -> fid );
781
788
else
@@ -784,7 +791,7 @@ int cifs_closedir(struct inode *inode, struct file *file)
784
791
/* not much we can do if it fails anyway, ignore rc */
785
792
rc = 0 ;
786
793
} else
787
- spin_unlock (& cifs_file_list_lock );
794
+ spin_unlock (& cfile -> file_info_lock );
788
795
789
796
buf = cfile -> srch_inf .ntwrk_buf_start ;
790
797
if (buf ) {
@@ -1728,12 +1735,13 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode,
1728
1735
{
1729
1736
struct cifsFileInfo * open_file = NULL ;
1730
1737
struct cifs_sb_info * cifs_sb = CIFS_SB (cifs_inode -> vfs_inode .i_sb );
1738
+ struct cifs_tcon * tcon = cifs_sb_master_tcon (cifs_sb );
1731
1739
1732
1740
/* only filter by fsuid on multiuser mounts */
1733
1741
if (!(cifs_sb -> mnt_cifs_flags & CIFS_MOUNT_MULTIUSER ))
1734
1742
fsuid_only = false;
1735
1743
1736
- spin_lock (& cifs_file_list_lock );
1744
+ spin_lock (& tcon -> open_file_lock );
1737
1745
/* we could simply get the first_list_entry since write-only entries
1738
1746
are always at the end of the list but since the first entry might
1739
1747
have a close pending, we go through the whole list */
@@ -1744,16 +1752,16 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode,
1744
1752
if (!open_file -> invalidHandle ) {
1745
1753
/* found a good file */
1746
1754
/* lock it so it will not be closed on us */
1747
- cifsFileInfo_get_locked (open_file );
1748
- spin_unlock (& cifs_file_list_lock );
1755
+ cifsFileInfo_get (open_file );
1756
+ spin_unlock (& tcon -> open_file_lock );
1749
1757
return open_file ;
1750
1758
} /* else might as well continue, and look for
1751
1759
another, or simply have the caller reopen it
1752
1760
again rather than trying to fix this handle */
1753
1761
} else /* write only file */
1754
1762
break ; /* write only files are last so must be done */
1755
1763
}
1756
- spin_unlock (& cifs_file_list_lock );
1764
+ spin_unlock (& tcon -> open_file_lock );
1757
1765
return NULL ;
1758
1766
}
1759
1767
@@ -1762,6 +1770,7 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode,
1762
1770
{
1763
1771
struct cifsFileInfo * open_file , * inv_file = NULL ;
1764
1772
struct cifs_sb_info * cifs_sb ;
1773
+ struct cifs_tcon * tcon ;
1765
1774
bool any_available = false;
1766
1775
int rc ;
1767
1776
unsigned int refind = 0 ;
@@ -1777,15 +1786,16 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode,
1777
1786
}
1778
1787
1779
1788
cifs_sb = CIFS_SB (cifs_inode -> vfs_inode .i_sb );
1789
+ tcon = cifs_sb_master_tcon (cifs_sb );
1780
1790
1781
1791
/* only filter by fsuid on multiuser mounts */
1782
1792
if (!(cifs_sb -> mnt_cifs_flags & CIFS_MOUNT_MULTIUSER ))
1783
1793
fsuid_only = false;
1784
1794
1785
- spin_lock (& cifs_file_list_lock );
1795
+ spin_lock (& tcon -> open_file_lock );
1786
1796
refind_writable :
1787
1797
if (refind > MAX_REOPEN_ATT ) {
1788
- spin_unlock (& cifs_file_list_lock );
1798
+ spin_unlock (& tcon -> open_file_lock );
1789
1799
return NULL ;
1790
1800
}
1791
1801
list_for_each_entry (open_file , & cifs_inode -> openFileList , flist ) {
@@ -1796,8 +1806,8 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode,
1796
1806
if (OPEN_FMODE (open_file -> f_flags ) & FMODE_WRITE ) {
1797
1807
if (!open_file -> invalidHandle ) {
1798
1808
/* found a good writable file */
1799
- cifsFileInfo_get_locked (open_file );
1800
- spin_unlock (& cifs_file_list_lock );
1809
+ cifsFileInfo_get (open_file );
1810
+ spin_unlock (& tcon -> open_file_lock );
1801
1811
return open_file ;
1802
1812
} else {
1803
1813
if (!inv_file )
@@ -1813,24 +1823,24 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode,
1813
1823
1814
1824
if (inv_file ) {
1815
1825
any_available = false;
1816
- cifsFileInfo_get_locked (inv_file );
1826
+ cifsFileInfo_get (inv_file );
1817
1827
}
1818
1828
1819
- spin_unlock (& cifs_file_list_lock );
1829
+ spin_unlock (& tcon -> open_file_lock );
1820
1830
1821
1831
if (inv_file ) {
1822
1832
rc = cifs_reopen_file (inv_file , false);
1823
1833
if (!rc )
1824
1834
return inv_file ;
1825
1835
else {
1826
- spin_lock (& cifs_file_list_lock );
1836
+ spin_lock (& tcon -> open_file_lock );
1827
1837
list_move_tail (& inv_file -> flist ,
1828
1838
& cifs_inode -> openFileList );
1829
- spin_unlock (& cifs_file_list_lock );
1839
+ spin_unlock (& tcon -> open_file_lock );
1830
1840
cifsFileInfo_put (inv_file );
1831
- spin_lock (& cifs_file_list_lock );
1832
1841
++ refind ;
1833
1842
inv_file = NULL ;
1843
+ spin_lock (& tcon -> open_file_lock );
1834
1844
goto refind_writable ;
1835
1845
}
1836
1846
}
@@ -3612,15 +3622,17 @@ static int cifs_readpage(struct file *file, struct page *page)
3612
3622
static int is_inode_writable (struct cifsInodeInfo * cifs_inode )
3613
3623
{
3614
3624
struct cifsFileInfo * open_file ;
3625
+ struct cifs_tcon * tcon =
3626
+ cifs_sb_master_tcon (CIFS_SB (cifs_inode -> vfs_inode .i_sb ));
3615
3627
3616
- spin_lock (& cifs_file_list_lock );
3628
+ spin_lock (& tcon -> open_file_lock );
3617
3629
list_for_each_entry (open_file , & cifs_inode -> openFileList , flist ) {
3618
3630
if (OPEN_FMODE (open_file -> f_flags ) & FMODE_WRITE ) {
3619
- spin_unlock (& cifs_file_list_lock );
3631
+ spin_unlock (& tcon -> open_file_lock );
3620
3632
return 1 ;
3621
3633
}
3622
3634
}
3623
- spin_unlock (& cifs_file_list_lock );
3635
+ spin_unlock (& tcon -> open_file_lock );
3624
3636
return 0 ;
3625
3637
}
3626
3638
0 commit comments