@@ -1876,40 +1876,43 @@ int nfs_generic_commit_list(struct inode *inode, struct list_head *head,
1876
1876
return status ;
1877
1877
}
1878
1878
1879
- int nfs_commit_inode (struct inode * inode , int how )
1879
+ static int __nfs_commit_inode (struct inode * inode , int how ,
1880
+ struct writeback_control * wbc )
1880
1881
{
1881
1882
LIST_HEAD (head );
1882
1883
struct nfs_commit_info cinfo ;
1883
1884
int may_wait = how & FLUSH_SYNC ;
1884
- int error = 0 ;
1885
- int res ;
1885
+ int ret , nscan ;
1886
1886
1887
1887
nfs_init_cinfo_from_inode (& cinfo , inode );
1888
1888
nfs_commit_begin (cinfo .mds );
1889
- res = nfs_scan_commit (inode , & head , & cinfo );
1890
- if (res )
1891
- error = nfs_generic_commit_list (inode , & head , how , & cinfo );
1889
+ for (;;) {
1890
+ ret = nscan = nfs_scan_commit (inode , & head , & cinfo );
1891
+ if (ret <= 0 )
1892
+ break ;
1893
+ ret = nfs_generic_commit_list (inode , & head , how , & cinfo );
1894
+ if (ret < 0 )
1895
+ break ;
1896
+ ret = 0 ;
1897
+ if (wbc && wbc -> sync_mode == WB_SYNC_NONE ) {
1898
+ if (nscan < wbc -> nr_to_write )
1899
+ wbc -> nr_to_write -= nscan ;
1900
+ else
1901
+ wbc -> nr_to_write = 0 ;
1902
+ }
1903
+ if (nscan < INT_MAX )
1904
+ break ;
1905
+ cond_resched ();
1906
+ }
1892
1907
nfs_commit_end (cinfo .mds );
1893
- if (res == 0 )
1894
- return res ;
1895
- if (error < 0 )
1896
- goto out_error ;
1897
- if (!may_wait )
1898
- goto out_mark_dirty ;
1899
- error = wait_on_commit (cinfo .mds );
1900
- if (error < 0 )
1901
- return error ;
1902
- return res ;
1903
- out_error :
1904
- res = error ;
1905
- /* Note: If we exit without ensuring that the commit is complete,
1906
- * we must mark the inode as dirty. Otherwise, future calls to
1907
- * sync_inode() with the WB_SYNC_ALL flag set will fail to ensure
1908
- * that the data is on the disk.
1909
- */
1910
- out_mark_dirty :
1911
- __mark_inode_dirty (inode , I_DIRTY_DATASYNC );
1912
- return res ;
1908
+ if (ret || !may_wait )
1909
+ return ret ;
1910
+ return wait_on_commit (cinfo .mds );
1911
+ }
1912
+
1913
+ int nfs_commit_inode (struct inode * inode , int how )
1914
+ {
1915
+ return __nfs_commit_inode (inode , how , NULL );
1913
1916
}
1914
1917
EXPORT_SYMBOL_GPL (nfs_commit_inode );
1915
1918
@@ -1919,11 +1922,11 @@ int nfs_write_inode(struct inode *inode, struct writeback_control *wbc)
1919
1922
int flags = FLUSH_SYNC ;
1920
1923
int ret = 0 ;
1921
1924
1922
- /* no commits means nothing needs to be done */
1923
- if (!atomic_long_read (& nfsi -> commit_info .ncommit ))
1924
- return ret ;
1925
-
1926
1925
if (wbc -> sync_mode == WB_SYNC_NONE ) {
1926
+ /* no commits means nothing needs to be done */
1927
+ if (!atomic_long_read (& nfsi -> commit_info .ncommit ))
1928
+ goto check_requests_outstanding ;
1929
+
1927
1930
/* Don't commit yet if this is a non-blocking flush and there
1928
1931
* are a lot of outstanding writes for this mapping.
1929
1932
*/
@@ -1934,16 +1937,16 @@ int nfs_write_inode(struct inode *inode, struct writeback_control *wbc)
1934
1937
flags = 0 ;
1935
1938
}
1936
1939
1937
- ret = nfs_commit_inode (inode , flags );
1938
- if (ret >= 0 ) {
1939
- if (wbc -> sync_mode == WB_SYNC_NONE ) {
1940
- if ( ret < wbc -> nr_to_write )
1941
- wbc -> nr_to_write -= ret ;
1942
- else
1943
- wbc -> nr_to_write = 0 ;
1944
- }
1945
- return 0 ;
1946
- }
1940
+ ret = __nfs_commit_inode (inode , flags , wbc );
1941
+ if (! ret ) {
1942
+ if (flags & FLUSH_SYNC )
1943
+ return 0 ;
1944
+ } else if ( atomic_long_read ( & nfsi -> commit_info . ncommit ))
1945
+ goto out_mark_dirty ;
1946
+
1947
+ check_requests_outstanding :
1948
+ if (! atomic_read ( & nfsi -> commit_info . rpcs_out ))
1949
+ return ret ;
1947
1950
out_mark_dirty :
1948
1951
__mark_inode_dirty (inode , I_DIRTY_DATASYNC );
1949
1952
return ret ;
0 commit comments