diff options
-rw-r--r-- | fs/ext4/mballoc.c | 182 |
1 files changed, 91 insertions, 91 deletions
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 5ef6daf0cdc6..fed5ac699141 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c | |||
@@ -910,6 +910,97 @@ out: | |||
910 | return err; | 910 | return err; |
911 | } | 911 | } |
912 | 912 | ||
913 | static noinline_for_stack | ||
914 | int ext4_mb_init_group(struct super_block *sb, ext4_group_t group) | ||
915 | { | ||
916 | |||
917 | int ret = 0; | ||
918 | void *bitmap; | ||
919 | int blocks_per_page; | ||
920 | int block, pnum, poff; | ||
921 | int num_grp_locked = 0; | ||
922 | struct ext4_group_info *this_grp; | ||
923 | struct ext4_sb_info *sbi = EXT4_SB(sb); | ||
924 | struct inode *inode = sbi->s_buddy_cache; | ||
925 | struct page *page = NULL, *bitmap_page = NULL; | ||
926 | |||
927 | mb_debug(1, "init group %u\n", group); | ||
928 | blocks_per_page = PAGE_CACHE_SIZE / sb->s_blocksize; | ||
929 | this_grp = ext4_get_group_info(sb, group); | ||
930 | /* | ||
931 | * This ensures we don't add group | ||
932 | * to this buddy cache via resize | ||
933 | */ | ||
934 | num_grp_locked = ext4_mb_get_buddy_cache_lock(sb, group); | ||
935 | if (!EXT4_MB_GRP_NEED_INIT(this_grp)) { | ||
936 | /* | ||
937 | * somebody initialized the group | ||
938 | * return without doing anything | ||
939 | */ | ||
940 | ret = 0; | ||
941 | goto err; | ||
942 | } | ||
943 | /* | ||
944 | * the buddy cache inode stores the block bitmap | ||
945 | * and buddy information in consecutive blocks. | ||
946 | * So for each group we need two blocks. | ||
947 | */ | ||
948 | block = group * 2; | ||
949 | pnum = block / blocks_per_page; | ||
950 | poff = block % blocks_per_page; | ||
951 | page = find_or_create_page(inode->i_mapping, pnum, GFP_NOFS); | ||
952 | if (page) { | ||
953 | BUG_ON(page->mapping != inode->i_mapping); | ||
954 | ret = ext4_mb_init_cache(page, NULL); | ||
955 | if (ret) { | ||
956 | unlock_page(page); | ||
957 | goto err; | ||
958 | } | ||
959 | unlock_page(page); | ||
960 | } | ||
961 | if (page == NULL || !PageUptodate(page)) { | ||
962 | ret = -EIO; | ||
963 | goto err; | ||
964 | } | ||
965 | mark_page_accessed(page); | ||
966 | bitmap_page = page; | ||
967 | bitmap = page_address(page) + (poff * sb->s_blocksize); | ||
968 | |||
969 | /* init buddy cache */ | ||
970 | block++; | ||
971 | pnum = block / blocks_per_page; | ||
972 | poff = block % blocks_per_page; | ||
973 | page = find_or_create_page(inode->i_mapping, pnum, GFP_NOFS); | ||
974 | if (page == bitmap_page) { | ||
975 | /* | ||
976 | * If both the bitmap and buddy are in | ||
977 | * the same page we don't need to force | ||
978 | * init the buddy | ||
979 | */ | ||
980 | unlock_page(page); | ||
981 | } else if (page) { | ||
982 | BUG_ON(page->mapping != inode->i_mapping); | ||
983 | ret = ext4_mb_init_cache(page, bitmap); | ||
984 | if (ret) { | ||
985 | unlock_page(page); | ||
986 | goto err; | ||
987 | } | ||
988 | unlock_page(page); | ||
989 | } | ||
990 | if (page == NULL || !PageUptodate(page)) { | ||
991 | ret = -EIO; | ||
992 | goto err; | ||
993 | } | ||
994 | mark_page_accessed(page); | ||
995 | err: | ||
996 | ext4_mb_put_buddy_cache_lock(sb, group, num_grp_locked); | ||
997 | if (bitmap_page) | ||
998 | page_cache_release(bitmap_page); | ||
999 | if (page) | ||
1000 | page_cache_release(page); | ||
1001 | return ret; | ||
1002 | } | ||
1003 | |||
913 | static noinline_for_stack int | 1004 | static noinline_for_stack int |
914 | ext4_mb_load_buddy(struct super_block *sb, ext4_group_t group, | 1005 | ext4_mb_load_buddy(struct super_block *sb, ext4_group_t group, |
915 | struct ext4_buddy *e4b) | 1006 | struct ext4_buddy *e4b) |
@@ -1839,97 +1930,6 @@ void ext4_mb_put_buddy_cache_lock(struct super_block *sb, | |||
1839 | 1930 | ||
1840 | } | 1931 | } |
1841 | 1932 | ||
1842 | static noinline_for_stack | ||
1843 | int ext4_mb_init_group(struct super_block *sb, ext4_group_t group) | ||
1844 | { | ||
1845 | |||
1846 | int ret; | ||
1847 | void *bitmap; | ||
1848 | int blocks_per_page; | ||
1849 | int block, pnum, poff; | ||
1850 | int num_grp_locked = 0; | ||
1851 | struct ext4_group_info *this_grp; | ||
1852 | struct ext4_sb_info *sbi = EXT4_SB(sb); | ||
1853 | struct inode *inode = sbi->s_buddy_cache; | ||
1854 | struct page *page = NULL, *bitmap_page = NULL; | ||
1855 | |||
1856 | mb_debug(1, "init group %u\n", group); | ||
1857 | blocks_per_page = PAGE_CACHE_SIZE / sb->s_blocksize; | ||
1858 | this_grp = ext4_get_group_info(sb, group); | ||
1859 | /* | ||
1860 | * This ensures we don't add group | ||
1861 | * to this buddy cache via resize | ||
1862 | */ | ||
1863 | num_grp_locked = ext4_mb_get_buddy_cache_lock(sb, group); | ||
1864 | if (!EXT4_MB_GRP_NEED_INIT(this_grp)) { | ||
1865 | /* | ||
1866 | * somebody initialized the group | ||
1867 | * return without doing anything | ||
1868 | */ | ||
1869 | ret = 0; | ||
1870 | goto err; | ||
1871 | } | ||
1872 | /* | ||
1873 | * the buddy cache inode stores the block bitmap | ||
1874 | * and buddy information in consecutive blocks. | ||
1875 | * So for each group we need two blocks. | ||
1876 | */ | ||
1877 | block = group * 2; | ||
1878 | pnum = block / blocks_per_page; | ||
1879 | poff = block % blocks_per_page; | ||
1880 | page = find_or_create_page(inode->i_mapping, pnum, GFP_NOFS); | ||
1881 | if (page) { | ||
1882 | BUG_ON(page->mapping != inode->i_mapping); | ||
1883 | ret = ext4_mb_init_cache(page, NULL); | ||
1884 | if (ret) { | ||
1885 | unlock_page(page); | ||
1886 | goto err; | ||
1887 | } | ||
1888 | unlock_page(page); | ||
1889 | } | ||
1890 | if (page == NULL || !PageUptodate(page)) { | ||
1891 | ret = -EIO; | ||
1892 | goto err; | ||
1893 | } | ||
1894 | mark_page_accessed(page); | ||
1895 | bitmap_page = page; | ||
1896 | bitmap = page_address(page) + (poff * sb->s_blocksize); | ||
1897 | |||
1898 | /* init buddy cache */ | ||
1899 | block++; | ||
1900 | pnum = block / blocks_per_page; | ||
1901 | poff = block % blocks_per_page; | ||
1902 | page = find_or_create_page(inode->i_mapping, pnum, GFP_NOFS); | ||
1903 | if (page == bitmap_page) { | ||
1904 | /* | ||
1905 | * If both the bitmap and buddy are in | ||
1906 | * the same page we don't need to force | ||
1907 | * init the buddy | ||
1908 | */ | ||
1909 | unlock_page(page); | ||
1910 | } else if (page) { | ||
1911 | BUG_ON(page->mapping != inode->i_mapping); | ||
1912 | ret = ext4_mb_init_cache(page, bitmap); | ||
1913 | if (ret) { | ||
1914 | unlock_page(page); | ||
1915 | goto err; | ||
1916 | } | ||
1917 | unlock_page(page); | ||
1918 | } | ||
1919 | if (page == NULL || !PageUptodate(page)) { | ||
1920 | ret = -EIO; | ||
1921 | goto err; | ||
1922 | } | ||
1923 | mark_page_accessed(page); | ||
1924 | err: | ||
1925 | ext4_mb_put_buddy_cache_lock(sb, group, num_grp_locked); | ||
1926 | if (bitmap_page) | ||
1927 | page_cache_release(bitmap_page); | ||
1928 | if (page) | ||
1929 | page_cache_release(page); | ||
1930 | return ret; | ||
1931 | } | ||
1932 | |||
1933 | static noinline_for_stack int | 1933 | static noinline_for_stack int |
1934 | ext4_mb_regular_allocator(struct ext4_allocation_context *ac) | 1934 | ext4_mb_regular_allocator(struct ext4_allocation_context *ac) |
1935 | { | 1935 | { |