diff options
Diffstat (limited to 'fs/nilfs2/segment.c')
| -rw-r--r-- | fs/nilfs2/segment.c | 44 |
1 files changed, 22 insertions, 22 deletions
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c index aa977549919e..51ff3d0a4ee2 100644 --- a/fs/nilfs2/segment.c +++ b/fs/nilfs2/segment.c | |||
| @@ -1829,26 +1829,13 @@ static int nilfs_segctor_write(struct nilfs_sc_info *sci, | |||
| 1829 | err = nilfs_segbuf_write(segbuf, &wi); | 1829 | err = nilfs_segbuf_write(segbuf, &wi); |
| 1830 | 1830 | ||
| 1831 | res = nilfs_segbuf_wait(segbuf, &wi); | 1831 | res = nilfs_segbuf_wait(segbuf, &wi); |
| 1832 | err = unlikely(err) ? : res; | 1832 | err = err ? : res; |
| 1833 | if (unlikely(err)) | 1833 | if (err) |
| 1834 | return err; | 1834 | return err; |
| 1835 | } | 1835 | } |
| 1836 | return 0; | 1836 | return 0; |
| 1837 | } | 1837 | } |
| 1838 | 1838 | ||
| 1839 | static int nilfs_page_has_uncleared_buffer(struct page *page) | ||
| 1840 | { | ||
| 1841 | struct buffer_head *head, *bh; | ||
| 1842 | |||
| 1843 | head = bh = page_buffers(page); | ||
| 1844 | do { | ||
| 1845 | if (buffer_dirty(bh) && !list_empty(&bh->b_assoc_buffers)) | ||
| 1846 | return 1; | ||
| 1847 | bh = bh->b_this_page; | ||
| 1848 | } while (bh != head); | ||
| 1849 | return 0; | ||
| 1850 | } | ||
| 1851 | |||
| 1852 | static void __nilfs_end_page_io(struct page *page, int err) | 1839 | static void __nilfs_end_page_io(struct page *page, int err) |
| 1853 | { | 1840 | { |
| 1854 | if (!err) { | 1841 | if (!err) { |
| @@ -1872,13 +1859,26 @@ static void nilfs_end_page_io(struct page *page, int err) | |||
| 1872 | if (!page) | 1859 | if (!page) |
| 1873 | return; | 1860 | return; |
| 1874 | 1861 | ||
| 1875 | if (buffer_nilfs_node(page_buffers(page)) && | 1862 | if (buffer_nilfs_node(page_buffers(page)) && !PageWriteback(page)) { |
| 1876 | nilfs_page_has_uncleared_buffer(page)) | 1863 | /* |
| 1877 | /* For b-tree node pages, this function may be called twice | 1864 | * For b-tree node pages, this function may be called twice |
| 1878 | or more because they might be split in a segment. | 1865 | * or more because they might be split in a segment. |
| 1879 | This check assures that cleanup has been done for all | 1866 | */ |
| 1880 | buffers in a split btnode page. */ | 1867 | if (PageDirty(page)) { |
| 1868 | /* | ||
| 1869 | * For pages holding split b-tree node buffers, dirty | ||
| 1870 | * flag on the buffers may be cleared discretely. | ||
| 1871 | * In that case, the page is once redirtied for | ||
| 1872 | * remaining buffers, and it must be cancelled if | ||
| 1873 | * all the buffers get cleaned later. | ||
| 1874 | */ | ||
| 1875 | lock_page(page); | ||
| 1876 | if (nilfs_page_buffers_clean(page)) | ||
| 1877 | __nilfs_clear_page_dirty(page); | ||
| 1878 | unlock_page(page); | ||
| 1879 | } | ||
| 1881 | return; | 1880 | return; |
| 1881 | } | ||
| 1882 | 1882 | ||
| 1883 | __nilfs_end_page_io(page, err); | 1883 | __nilfs_end_page_io(page, err); |
| 1884 | } | 1884 | } |
| @@ -1940,7 +1940,7 @@ static void nilfs_segctor_abort_write(struct nilfs_sc_info *sci, | |||
| 1940 | } | 1940 | } |
| 1941 | if (bh->b_page != fs_page) { | 1941 | if (bh->b_page != fs_page) { |
| 1942 | nilfs_end_page_io(fs_page, err); | 1942 | nilfs_end_page_io(fs_page, err); |
| 1943 | if (unlikely(fs_page == failed_page)) | 1943 | if (fs_page && fs_page == failed_page) |
| 1944 | goto done; | 1944 | goto done; |
| 1945 | fs_page = bh->b_page; | 1945 | fs_page = bh->b_page; |
| 1946 | } | 1946 | } |
