diff options
Diffstat (limited to 'fs/reiserfs/super.c')
-rw-r--r-- | fs/reiserfs/super.c | 107 |
1 files changed, 67 insertions, 40 deletions
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index b35b87744983..4b80ab95d338 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c | |||
@@ -866,8 +866,9 @@ static int reiserfs_parse_options (struct super_block * s, char * options, /* st | |||
866 | {"jdev", .arg_required = 'j', .values = NULL}, | 866 | {"jdev", .arg_required = 'j', .values = NULL}, |
867 | {"nolargeio", .arg_required = 'w', .values = NULL}, | 867 | {"nolargeio", .arg_required = 'w', .values = NULL}, |
868 | {"commit", .arg_required = 'c', .values = NULL}, | 868 | {"commit", .arg_required = 'c', .values = NULL}, |
869 | {"usrquota",}, | 869 | {"usrquota", .setmask = 1<<REISERFS_QUOTA}, |
870 | {"grpquota",}, | 870 | {"grpquota", .setmask = 1<<REISERFS_QUOTA}, |
871 | {"noquota", .clrmask = 1<<REISERFS_QUOTA}, | ||
871 | {"errors", .arg_required = 'e', .values = error_actions}, | 872 | {"errors", .arg_required = 'e', .values = error_actions}, |
872 | {"usrjquota", .arg_required = 'u'|(1<<REISERFS_OPT_ALLOWEMPTY), .values = NULL}, | 873 | {"usrjquota", .arg_required = 'u'|(1<<REISERFS_OPT_ALLOWEMPTY), .values = NULL}, |
873 | {"grpjquota", .arg_required = 'g'|(1<<REISERFS_OPT_ALLOWEMPTY), .values = NULL}, | 874 | {"grpjquota", .arg_required = 'g'|(1<<REISERFS_OPT_ALLOWEMPTY), .values = NULL}, |
@@ -964,6 +965,7 @@ static int reiserfs_parse_options (struct super_block * s, char * options, /* st | |||
964 | return 0; | 965 | return 0; |
965 | } | 966 | } |
966 | strcpy(REISERFS_SB(s)->s_qf_names[qtype], arg); | 967 | strcpy(REISERFS_SB(s)->s_qf_names[qtype], arg); |
968 | *mount_options |= 1<<REISERFS_QUOTA; | ||
967 | } | 969 | } |
968 | else { | 970 | else { |
969 | if (REISERFS_SB(s)->s_qf_names[qtype]) { | 971 | if (REISERFS_SB(s)->s_qf_names[qtype]) { |
@@ -995,7 +997,13 @@ static int reiserfs_parse_options (struct super_block * s, char * options, /* st | |||
995 | reiserfs_warning(s, "reiserfs_parse_options: journalled quota format not specified."); | 997 | reiserfs_warning(s, "reiserfs_parse_options: journalled quota format not specified."); |
996 | return 0; | 998 | return 0; |
997 | } | 999 | } |
1000 | /* This checking is not precise wrt the quota type but for our purposes it is sufficient */ | ||
1001 | if (!(*mount_options & (1<<REISERFS_QUOTA)) && sb_any_quota_enabled(s)) { | ||
1002 | reiserfs_warning(s, "reiserfs_parse_options: quota options must be present when quota is turned on."); | ||
1003 | return 0; | ||
1004 | } | ||
998 | #endif | 1005 | #endif |
1006 | |||
999 | return 1; | 1007 | return 1; |
1000 | } | 1008 | } |
1001 | 1009 | ||
@@ -1045,10 +1053,9 @@ static void handle_barrier_mode(struct super_block *s, unsigned long bits) { | |||
1045 | 1053 | ||
1046 | static void handle_attrs( struct super_block *s ) | 1054 | static void handle_attrs( struct super_block *s ) |
1047 | { | 1055 | { |
1048 | struct reiserfs_super_block * rs; | 1056 | struct reiserfs_super_block * rs = SB_DISK_SUPER_BLOCK (s); |
1049 | 1057 | ||
1050 | if( reiserfs_attrs( s ) ) { | 1058 | if( reiserfs_attrs( s ) ) { |
1051 | rs = SB_DISK_SUPER_BLOCK (s); | ||
1052 | if( old_format_only(s) ) { | 1059 | if( old_format_only(s) ) { |
1053 | reiserfs_warning(s, "reiserfs: cannot support attributes on 3.5.x disk format" ); | 1060 | reiserfs_warning(s, "reiserfs: cannot support attributes on 3.5.x disk format" ); |
1054 | REISERFS_SB(s) -> s_mount_opt &= ~ ( 1 << REISERFS_ATTRS ); | 1061 | REISERFS_SB(s) -> s_mount_opt &= ~ ( 1 << REISERFS_ATTRS ); |
@@ -1058,6 +1065,8 @@ static void handle_attrs( struct super_block *s ) | |||
1058 | reiserfs_warning(s, "reiserfs: cannot support attributes until flag is set in super-block" ); | 1065 | reiserfs_warning(s, "reiserfs: cannot support attributes until flag is set in super-block" ); |
1059 | REISERFS_SB(s) -> s_mount_opt &= ~ ( 1 << REISERFS_ATTRS ); | 1066 | REISERFS_SB(s) -> s_mount_opt &= ~ ( 1 << REISERFS_ATTRS ); |
1060 | } | 1067 | } |
1068 | } else if (le32_to_cpu( rs -> s_flags ) & reiserfs_attrs_cleared) { | ||
1069 | REISERFS_SB(s)->s_mount_opt |= REISERFS_ATTRS; | ||
1061 | } | 1070 | } |
1062 | } | 1071 | } |
1063 | 1072 | ||
@@ -1105,6 +1114,7 @@ static int reiserfs_remount (struct super_block * s, int * mount_flags, char * a | |||
1105 | safe_mask |= 1 << REISERFS_ERROR_RO; | 1114 | safe_mask |= 1 << REISERFS_ERROR_RO; |
1106 | safe_mask |= 1 << REISERFS_ERROR_CONTINUE; | 1115 | safe_mask |= 1 << REISERFS_ERROR_CONTINUE; |
1107 | safe_mask |= 1 << REISERFS_ERROR_PANIC; | 1116 | safe_mask |= 1 << REISERFS_ERROR_PANIC; |
1117 | safe_mask |= 1 << REISERFS_QUOTA; | ||
1108 | 1118 | ||
1109 | /* Update the bitmask, taking care to keep | 1119 | /* Update the bitmask, taking care to keep |
1110 | * the bits we're not allowed to change here */ | 1120 | * the bits we're not allowed to change here */ |
@@ -1841,13 +1851,18 @@ static int reiserfs_statfs (struct super_block * s, struct kstatfs * buf) | |||
1841 | static int reiserfs_dquot_initialize(struct inode *inode, int type) | 1851 | static int reiserfs_dquot_initialize(struct inode *inode, int type) |
1842 | { | 1852 | { |
1843 | struct reiserfs_transaction_handle th; | 1853 | struct reiserfs_transaction_handle th; |
1844 | int ret; | 1854 | int ret, err; |
1845 | 1855 | ||
1846 | /* We may create quota structure so we need to reserve enough blocks */ | 1856 | /* We may create quota structure so we need to reserve enough blocks */ |
1847 | reiserfs_write_lock(inode->i_sb); | 1857 | reiserfs_write_lock(inode->i_sb); |
1848 | journal_begin(&th, inode->i_sb, 2*REISERFS_QUOTA_INIT_BLOCKS); | 1858 | ret = journal_begin(&th, inode->i_sb, 2*REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb)); |
1859 | if (ret) | ||
1860 | goto out; | ||
1849 | ret = dquot_initialize(inode, type); | 1861 | ret = dquot_initialize(inode, type); |
1850 | journal_end(&th, inode->i_sb, 2*REISERFS_QUOTA_INIT_BLOCKS); | 1862 | err = journal_end(&th, inode->i_sb, 2*REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb)); |
1863 | if (!ret && err) | ||
1864 | ret = err; | ||
1865 | out: | ||
1851 | reiserfs_write_unlock(inode->i_sb); | 1866 | reiserfs_write_unlock(inode->i_sb); |
1852 | return ret; | 1867 | return ret; |
1853 | } | 1868 | } |
@@ -1855,13 +1870,18 @@ static int reiserfs_dquot_initialize(struct inode *inode, int type) | |||
1855 | static int reiserfs_dquot_drop(struct inode *inode) | 1870 | static int reiserfs_dquot_drop(struct inode *inode) |
1856 | { | 1871 | { |
1857 | struct reiserfs_transaction_handle th; | 1872 | struct reiserfs_transaction_handle th; |
1858 | int ret; | 1873 | int ret, err; |
1859 | 1874 | ||
1860 | /* We may delete quota structure so we need to reserve enough blocks */ | 1875 | /* We may delete quota structure so we need to reserve enough blocks */ |
1861 | reiserfs_write_lock(inode->i_sb); | 1876 | reiserfs_write_lock(inode->i_sb); |
1862 | journal_begin(&th, inode->i_sb, 2*REISERFS_QUOTA_INIT_BLOCKS); | 1877 | ret = journal_begin(&th, inode->i_sb, 2*REISERFS_QUOTA_DEL_BLOCKS(inode->i_sb)); |
1878 | if (ret) | ||
1879 | goto out; | ||
1863 | ret = dquot_drop(inode); | 1880 | ret = dquot_drop(inode); |
1864 | journal_end(&th, inode->i_sb, 2*REISERFS_QUOTA_INIT_BLOCKS); | 1881 | err = journal_end(&th, inode->i_sb, 2*REISERFS_QUOTA_DEL_BLOCKS(inode->i_sb)); |
1882 | if (!ret && err) | ||
1883 | ret = err; | ||
1884 | out: | ||
1865 | reiserfs_write_unlock(inode->i_sb); | 1885 | reiserfs_write_unlock(inode->i_sb); |
1866 | return ret; | 1886 | return ret; |
1867 | } | 1887 | } |
@@ -1869,12 +1889,17 @@ static int reiserfs_dquot_drop(struct inode *inode) | |||
1869 | static int reiserfs_write_dquot(struct dquot *dquot) | 1889 | static int reiserfs_write_dquot(struct dquot *dquot) |
1870 | { | 1890 | { |
1871 | struct reiserfs_transaction_handle th; | 1891 | struct reiserfs_transaction_handle th; |
1872 | int ret; | 1892 | int ret, err; |
1873 | 1893 | ||
1874 | reiserfs_write_lock(dquot->dq_sb); | 1894 | reiserfs_write_lock(dquot->dq_sb); |
1875 | journal_begin(&th, dquot->dq_sb, REISERFS_QUOTA_TRANS_BLOCKS); | 1895 | ret = journal_begin(&th, dquot->dq_sb, REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_sb)); |
1896 | if (ret) | ||
1897 | goto out; | ||
1876 | ret = dquot_commit(dquot); | 1898 | ret = dquot_commit(dquot); |
1877 | journal_end(&th, dquot->dq_sb, REISERFS_QUOTA_TRANS_BLOCKS); | 1899 | err = journal_end(&th, dquot->dq_sb, REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_sb)); |
1900 | if (!ret && err) | ||
1901 | ret = err; | ||
1902 | out: | ||
1878 | reiserfs_write_unlock(dquot->dq_sb); | 1903 | reiserfs_write_unlock(dquot->dq_sb); |
1879 | return ret; | 1904 | return ret; |
1880 | } | 1905 | } |
@@ -1882,12 +1907,17 @@ static int reiserfs_write_dquot(struct dquot *dquot) | |||
1882 | static int reiserfs_acquire_dquot(struct dquot *dquot) | 1907 | static int reiserfs_acquire_dquot(struct dquot *dquot) |
1883 | { | 1908 | { |
1884 | struct reiserfs_transaction_handle th; | 1909 | struct reiserfs_transaction_handle th; |
1885 | int ret; | 1910 | int ret, err; |
1886 | 1911 | ||
1887 | reiserfs_write_lock(dquot->dq_sb); | 1912 | reiserfs_write_lock(dquot->dq_sb); |
1888 | journal_begin(&th, dquot->dq_sb, REISERFS_QUOTA_INIT_BLOCKS); | 1913 | ret = journal_begin(&th, dquot->dq_sb, REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_sb)); |
1914 | if (ret) | ||
1915 | goto out; | ||
1889 | ret = dquot_acquire(dquot); | 1916 | ret = dquot_acquire(dquot); |
1890 | journal_end(&th, dquot->dq_sb, REISERFS_QUOTA_INIT_BLOCKS); | 1917 | err = journal_end(&th, dquot->dq_sb, REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_sb)); |
1918 | if (!ret && err) | ||
1919 | ret = err; | ||
1920 | out: | ||
1891 | reiserfs_write_unlock(dquot->dq_sb); | 1921 | reiserfs_write_unlock(dquot->dq_sb); |
1892 | return ret; | 1922 | return ret; |
1893 | } | 1923 | } |
@@ -1895,12 +1925,17 @@ static int reiserfs_acquire_dquot(struct dquot *dquot) | |||
1895 | static int reiserfs_release_dquot(struct dquot *dquot) | 1925 | static int reiserfs_release_dquot(struct dquot *dquot) |
1896 | { | 1926 | { |
1897 | struct reiserfs_transaction_handle th; | 1927 | struct reiserfs_transaction_handle th; |
1898 | int ret; | 1928 | int ret, err; |
1899 | 1929 | ||
1900 | reiserfs_write_lock(dquot->dq_sb); | 1930 | reiserfs_write_lock(dquot->dq_sb); |
1901 | journal_begin(&th, dquot->dq_sb, REISERFS_QUOTA_INIT_BLOCKS); | 1931 | ret = journal_begin(&th, dquot->dq_sb, REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_sb)); |
1932 | if (ret) | ||
1933 | goto out; | ||
1902 | ret = dquot_release(dquot); | 1934 | ret = dquot_release(dquot); |
1903 | journal_end(&th, dquot->dq_sb, REISERFS_QUOTA_INIT_BLOCKS); | 1935 | err = journal_end(&th, dquot->dq_sb, REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_sb)); |
1936 | if (!ret && err) | ||
1937 | ret = err; | ||
1938 | out: | ||
1904 | reiserfs_write_unlock(dquot->dq_sb); | 1939 | reiserfs_write_unlock(dquot->dq_sb); |
1905 | return ret; | 1940 | return ret; |
1906 | } | 1941 | } |
@@ -1920,39 +1955,29 @@ static int reiserfs_mark_dquot_dirty(struct dquot *dquot) | |||
1920 | static int reiserfs_write_info(struct super_block *sb, int type) | 1955 | static int reiserfs_write_info(struct super_block *sb, int type) |
1921 | { | 1956 | { |
1922 | struct reiserfs_transaction_handle th; | 1957 | struct reiserfs_transaction_handle th; |
1923 | int ret; | 1958 | int ret, err; |
1924 | 1959 | ||
1925 | /* Data block + inode block */ | 1960 | /* Data block + inode block */ |
1926 | reiserfs_write_lock(sb); | 1961 | reiserfs_write_lock(sb); |
1927 | journal_begin(&th, sb, 2); | 1962 | ret = journal_begin(&th, sb, 2); |
1963 | if (ret) | ||
1964 | goto out; | ||
1928 | ret = dquot_commit_info(sb, type); | 1965 | ret = dquot_commit_info(sb, type); |
1929 | journal_end(&th, sb, 2); | 1966 | err = journal_end(&th, sb, 2); |
1967 | if (!ret && err) | ||
1968 | ret = err; | ||
1969 | out: | ||
1930 | reiserfs_write_unlock(sb); | 1970 | reiserfs_write_unlock(sb); |
1931 | return ret; | 1971 | return ret; |
1932 | } | 1972 | } |
1933 | 1973 | ||
1934 | /* | 1974 | /* |
1935 | * Turn on quotas during mount time - we need to find | 1975 | * Turn on quotas during mount time - we need to find the quota file and such... |
1936 | * the quota file and such... | ||
1937 | */ | 1976 | */ |
1938 | static int reiserfs_quota_on_mount(struct super_block *sb, int type) | 1977 | static int reiserfs_quota_on_mount(struct super_block *sb, int type) |
1939 | { | 1978 | { |
1940 | int err; | 1979 | return vfs_quota_on_mount(sb, REISERFS_SB(sb)->s_qf_names[type], |
1941 | struct dentry *dentry; | 1980 | REISERFS_SB(sb)->s_jquota_fmt, type); |
1942 | struct qstr name = { .name = REISERFS_SB(sb)->s_qf_names[type], | ||
1943 | .hash = 0, | ||
1944 | .len = strlen(REISERFS_SB(sb)->s_qf_names[type])}; | ||
1945 | |||
1946 | dentry = lookup_hash(&name, sb->s_root); | ||
1947 | if (IS_ERR(dentry)) | ||
1948 | return PTR_ERR(dentry); | ||
1949 | err = vfs_quota_on_mount(type, REISERFS_SB(sb)->s_jquota_fmt, dentry); | ||
1950 | /* Now invalidate and put the dentry - quota got its own reference | ||
1951 | * to inode and dentry has at least wrong hash so we had better | ||
1952 | * throw it away */ | ||
1953 | d_invalidate(dentry); | ||
1954 | dput(dentry); | ||
1955 | return err; | ||
1956 | } | 1981 | } |
1957 | 1982 | ||
1958 | /* | 1983 | /* |
@@ -1963,6 +1988,8 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id, ch | |||
1963 | int err; | 1988 | int err; |
1964 | struct nameidata nd; | 1989 | struct nameidata nd; |
1965 | 1990 | ||
1991 | if (!(REISERFS_SB(sb)->s_mount_opt & (1<<REISERFS_QUOTA))) | ||
1992 | return -EINVAL; | ||
1966 | err = path_lookup(path, LOOKUP_FOLLOW, &nd); | 1993 | err = path_lookup(path, LOOKUP_FOLLOW, &nd); |
1967 | if (err) | 1994 | if (err) |
1968 | return err; | 1995 | return err; |