resize.c (93f9052643409c13b3b5f76833865087351f55b8) resize.c (1c6bd7173d66b3dfdefcedb38cabc1fb03997509)
1/*
2 * linux/fs/ext4/resize.c
3 *
4 * Support for resizing an ext4 filesystem while it is mounted.
5 *
6 * Copyright (C) 2001, 2002 Andreas Dilger <adilger@clusterfs.com>
7 *
8 * This could probably be made into a module, because it is not often in use.

--- 1742 unchanged lines hidden (view full) ---

1751 return -ENOSPC;
1752 }
1753 brelse(bh);
1754
1755 err = ext4_group_extend_no_check(sb, o_blocks_count, add);
1756 return err;
1757} /* ext4_group_extend */
1758
1/*
2 * linux/fs/ext4/resize.c
3 *
4 * Support for resizing an ext4 filesystem while it is mounted.
5 *
6 * Copyright (C) 2001, 2002 Andreas Dilger <adilger@clusterfs.com>
7 *
8 * This could probably be made into a module, because it is not often in use.

--- 1742 unchanged lines hidden (view full) ---

1751 return -ENOSPC;
1752 }
1753 brelse(bh);
1754
1755 err = ext4_group_extend_no_check(sb, o_blocks_count, add);
1756 return err;
1757} /* ext4_group_extend */
1758
1759
1760static int num_desc_blocks(struct super_block *sb, ext4_group_t groups)
1761{
1762 return (groups + EXT4_DESC_PER_BLOCK(sb) - 1) / EXT4_DESC_PER_BLOCK(sb);
1763}
1764
1759/*
1765/*
1766 * Release the resize inode and drop the resize_inode feature if there
1767 * are no more reserved gdt blocks, and then convert the file system
1768 * to enable meta_bg
1769 */
1770static int ext4_convert_meta_bg(struct super_block *sb, struct inode *inode)
1771{
1772 handle_t *handle;
1773 struct ext4_sb_info *sbi = EXT4_SB(sb);
1774 struct ext4_super_block *es = sbi->s_es;
1775 struct ext4_inode_info *ei = 0;
1776 ext4_fsblk_t nr;
1777 int i, ret, err = 0;
1778 int credits = 1;
1779
1780 ext4_msg(sb, KERN_INFO, "Converting file system to meta_bg");
1781 if (EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_RESIZE_INODE)) {
1782 if (es->s_reserved_gdt_blocks) {
1783 ext4_error(sb, "Unexpected non-zero "
1784 "s_reserved_gdt_blocks");
1785 return -EPERM;
1786 }
1787 if (!inode) {
1788 ext4_error(sb, "Unexpected NULL resize_inode");
1789 return -EPERM;
1790 }
1791 ei = EXT4_I(inode);
1792
1793 /* Do a quick sanity check of the resize inode */
1794 if (inode->i_blocks != 1 << (inode->i_blkbits - 9))
1795 goto invalid_resize_inode;
1796 for (i = 0; i < EXT4_N_BLOCKS; i++) {
1797 if (i == EXT4_DIND_BLOCK) {
1798 if (ei->i_data[i])
1799 continue;
1800 else
1801 goto invalid_resize_inode;
1802 }
1803 if (ei->i_data[i])
1804 goto invalid_resize_inode;
1805 }
1806 credits += 3; /* block bitmap, bg descriptor, resize inode */
1807 }
1808
1809 handle = ext4_journal_start_sb(sb, credits);
1810 if (IS_ERR(handle))
1811 return PTR_ERR(handle);
1812
1813 err = ext4_journal_get_write_access(handle, sbi->s_sbh);
1814 if (err)
1815 goto errout;
1816
1817 EXT4_CLEAR_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_RESIZE_INODE);
1818 EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_META_BG);
1819 sbi->s_es->s_first_meta_bg =
1820 cpu_to_le32(num_desc_blocks(sb, sbi->s_groups_count));
1821
1822 err = ext4_handle_dirty_super(handle, sb);
1823 if (err) {
1824 ext4_std_error(sb, err);
1825 goto errout;
1826 }
1827
1828 if (inode) {
1829 nr = le32_to_cpu(ei->i_data[EXT4_DIND_BLOCK]);
1830 ext4_free_blocks(handle, inode, NULL, nr, 1,
1831 EXT4_FREE_BLOCKS_METADATA |
1832 EXT4_FREE_BLOCKS_FORGET);
1833 ei->i_data[EXT4_DIND_BLOCK] = 0;
1834 inode->i_blocks = 0;
1835
1836 err = ext4_mark_inode_dirty(handle, inode);
1837 if (err)
1838 ext4_std_error(sb, err);
1839 }
1840
1841errout:
1842 ret = ext4_journal_stop(handle);
1843 if (!err)
1844 err = ret;
1845 return ret;
1846
1847invalid_resize_inode:
1848 ext4_error(sb, "corrupted/inconsistent resize inode");
1849 return -EINVAL;
1850}
1851
1852/*
1760 * ext4_resize_fs() resizes a fs to new size specified by @n_blocks_count
1761 *
1762 * @sb: super block of the fs to be resized
1763 * @n_blocks_count: the number of blocks resides in the resized fs
1764 */
1765int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count)
1766{
1767 struct ext4_new_flex_group_data *flex_gd = NULL;
1768 struct ext4_sb_info *sbi = EXT4_SB(sb);
1769 struct ext4_super_block *es = sbi->s_es;
1770 struct buffer_head *bh;
1771 struct inode *resize_inode = NULL;
1772 ext4_grpblk_t add, offset;
1773 unsigned long n_desc_blocks;
1774 unsigned long o_desc_blocks;
1853 * ext4_resize_fs() resizes a fs to new size specified by @n_blocks_count
1854 *
1855 * @sb: super block of the fs to be resized
1856 * @n_blocks_count: the number of blocks resides in the resized fs
1857 */
1858int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count)
1859{
1860 struct ext4_new_flex_group_data *flex_gd = NULL;
1861 struct ext4_sb_info *sbi = EXT4_SB(sb);
1862 struct ext4_super_block *es = sbi->s_es;
1863 struct buffer_head *bh;
1864 struct inode *resize_inode = NULL;
1865 ext4_grpblk_t add, offset;
1866 unsigned long n_desc_blocks;
1867 unsigned long o_desc_blocks;
1775 unsigned long desc_blocks;
1776 ext4_group_t o_group;
1777 ext4_group_t n_group;
1778 ext4_fsblk_t o_blocks_count;
1868 ext4_group_t o_group;
1869 ext4_group_t n_group;
1870 ext4_fsblk_t o_blocks_count;
1871 ext4_fsblk_t n_blocks_count_retry = 0;
1779 int err = 0, flexbg_size = 1 << sbi->s_log_groups_per_flex;
1780 int meta_bg;
1781
1872 int err = 0, flexbg_size = 1 << sbi->s_log_groups_per_flex;
1873 int meta_bg;
1874
1875retry:
1782 o_blocks_count = ext4_blocks_count(es);
1783
1784 if (test_opt(sb, DEBUG))
1785 ext4_msg(sb, KERN_DEBUG, "resizing filesystem from %llu "
1786 "to %llu blocks", o_blocks_count, n_blocks_count);
1787
1788 if (n_blocks_count < o_blocks_count) {
1789 /* On-line shrinking not supported */
1790 ext4_warning(sb, "can't shrink FS - resize aborted");
1791 return -EINVAL;
1792 }
1793
1794 if (n_blocks_count == o_blocks_count)
1795 /* Nothing need to do */
1796 return 0;
1797
1798 ext4_get_group_no_and_offset(sb, n_blocks_count - 1, &n_group, &offset);
1799 ext4_get_group_no_and_offset(sb, o_blocks_count - 1, &o_group, &offset);
1800
1876 o_blocks_count = ext4_blocks_count(es);
1877
1878 if (test_opt(sb, DEBUG))
1879 ext4_msg(sb, KERN_DEBUG, "resizing filesystem from %llu "
1880 "to %llu blocks", o_blocks_count, n_blocks_count);
1881
1882 if (n_blocks_count < o_blocks_count) {
1883 /* On-line shrinking not supported */
1884 ext4_warning(sb, "can't shrink FS - resize aborted");
1885 return -EINVAL;
1886 }
1887
1888 if (n_blocks_count == o_blocks_count)
1889 /* Nothing need to do */
1890 return 0;
1891
1892 ext4_get_group_no_and_offset(sb, n_blocks_count - 1, &n_group, &offset);
1893 ext4_get_group_no_and_offset(sb, o_blocks_count - 1, &o_group, &offset);
1894
1801 n_desc_blocks = (n_group + EXT4_DESC_PER_BLOCK(sb)) /
1802 EXT4_DESC_PER_BLOCK(sb);
1803 o_desc_blocks = (sbi->s_groups_count + EXT4_DESC_PER_BLOCK(sb) - 1) /
1804 EXT4_DESC_PER_BLOCK(sb);
1805 desc_blocks = n_desc_blocks - o_desc_blocks;
1895 n_desc_blocks = num_desc_blocks(sb, n_group + 1);
1896 o_desc_blocks = num_desc_blocks(sb, sbi->s_groups_count);
1806
1807 meta_bg = EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_META_BG);
1808
1809 if (EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_RESIZE_INODE)) {
1810 if (meta_bg) {
1811 ext4_error(sb, "resize_inode and meta_bg enabled "
1812 "simultaneously");
1813 return -EINVAL;
1814 }
1897
1898 meta_bg = EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_META_BG);
1899
1900 if (EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_RESIZE_INODE)) {
1901 if (meta_bg) {
1902 ext4_error(sb, "resize_inode and meta_bg enabled "
1903 "simultaneously");
1904 return -EINVAL;
1905 }
1815 if (le16_to_cpu(es->s_reserved_gdt_blocks) < desc_blocks) {
1816 ext4_warning(sb,
1817 "No reserved GDT blocks, can't resize");
1818 return -EPERM;
1906 if (n_desc_blocks > o_desc_blocks +
1907 le16_to_cpu(es->s_reserved_gdt_blocks)) {
1908 n_blocks_count_retry = n_blocks_count;
1909 n_desc_blocks = o_desc_blocks +
1910 le16_to_cpu(es->s_reserved_gdt_blocks);
1911 n_group = n_desc_blocks * EXT4_DESC_PER_BLOCK(sb);
1912 n_blocks_count = n_group * EXT4_BLOCKS_PER_GROUP(sb);
1913 n_group--; /* set to last group number */
1819 }
1914 }
1820 resize_inode = ext4_iget(sb, EXT4_RESIZE_INO);
1915
1916 if (!resize_inode)
1917 resize_inode = ext4_iget(sb, EXT4_RESIZE_INO);
1821 if (IS_ERR(resize_inode)) {
1822 ext4_warning(sb, "Error opening resize inode");
1823 return PTR_ERR(resize_inode);
1824 }
1918 if (IS_ERR(resize_inode)) {
1919 ext4_warning(sb, "Error opening resize inode");
1920 return PTR_ERR(resize_inode);
1921 }
1825 } else if (!meta_bg) {
1826 ext4_warning(sb, "File system features do not permit "
1827 "online resize");
1828 return -EPERM;
1829 }
1830
1922 }
1923
1924 if ((!resize_inode && !meta_bg) || n_group == o_group) {
1925 err = ext4_convert_meta_bg(sb, resize_inode);
1926 if (err)
1927 goto out;
1928 if (resize_inode) {
1929 iput(resize_inode);
1930 resize_inode = NULL;
1931 }
1932 if (n_blocks_count_retry) {
1933 n_blocks_count = n_blocks_count_retry;
1934 n_blocks_count_retry = 0;
1935 goto retry;
1936 }
1937 }
1938
1831 /* See if the device is actually as big as what was requested */
1832 bh = sb_bread(sb, n_blocks_count - 1);
1833 if (!bh) {
1834 ext4_warning(sb, "can't read last block, resize aborted");
1835 return -ENOSPC;
1836 }
1837 brelse(bh);
1838

--- 32 unchanged lines hidden (view full) ---

1871 flexbg_size)) {
1872 if (ext4_alloc_group_tables(sb, flex_gd, flexbg_size) != 0)
1873 break;
1874 err = ext4_flex_group_add(sb, resize_inode, flex_gd);
1875 if (unlikely(err))
1876 break;
1877 }
1878
1939 /* See if the device is actually as big as what was requested */
1940 bh = sb_bread(sb, n_blocks_count - 1);
1941 if (!bh) {
1942 ext4_warning(sb, "can't read last block, resize aborted");
1943 return -ENOSPC;
1944 }
1945 brelse(bh);
1946

--- 32 unchanged lines hidden (view full) ---

1979 flexbg_size)) {
1980 if (ext4_alloc_group_tables(sb, flex_gd, flexbg_size) != 0)
1981 break;
1982 err = ext4_flex_group_add(sb, resize_inode, flex_gd);
1983 if (unlikely(err))
1984 break;
1985 }
1986
1987 if (!err && n_blocks_count_retry) {
1988 n_blocks_count = n_blocks_count_retry;
1989 n_blocks_count_retry = 0;
1990 free_flex_gd(flex_gd);
1991 flex_gd = NULL;
1992 goto retry;
1993 }
1994
1879out:
1880 if (flex_gd)
1881 free_flex_gd(flex_gd);
1882 if (resize_inode != NULL)
1883 iput(resize_inode);
1884 if (test_opt(sb, DEBUG))
1995out:
1996 if (flex_gd)
1997 free_flex_gd(flex_gd);
1998 if (resize_inode != NULL)
1999 iput(resize_inode);
2000 if (test_opt(sb, DEBUG))
1885 ext4_msg(sb, KERN_DEBUG, "resized filesystem from %llu "
1886 "upto %llu blocks", o_blocks_count, n_blocks_count);
2001 ext4_msg(sb, KERN_DEBUG, "resized filesystem to %llu",
2002 n_blocks_count);
1887 return err;
1888}
2003 return err;
2004}