diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-03-05 16:20:53 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-03-05 16:20:53 -0500 |
commit | e213e26ab3988c516c06eba4dcd030ac052f6dc9 (patch) | |
tree | 6e26fbdbb842b387697d73daf6e70cf718269a77 /fs/ext3/super.c | |
parent | c812a51d11bbe983f4c24e32b59b265705ddd3c2 (diff) | |
parent | efd8f0e6f6c1faa041f228d7113bd3a9db802d49 (diff) |
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs-2.6
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs-2.6: (33 commits)
quota: stop using QUOTA_OK / NO_QUOTA
dquot: cleanup dquot initialize routine
dquot: move dquot initialization responsibility into the filesystem
dquot: cleanup dquot drop routine
dquot: move dquot drop responsibility into the filesystem
dquot: cleanup dquot transfer routine
dquot: move dquot transfer responsibility into the filesystem
dquot: cleanup inode allocation / freeing routines
dquot: cleanup space allocation / freeing routines
ext3: add writepage sanity checks
ext3: Truncate allocated blocks if direct IO write fails to update i_size
quota: Properly invalidate caches even for filesystems with blocksize < pagesize
quota: generalize quota transfer interface
quota: sb_quota state flags cleanup
jbd: Delay discarding buffers in journal_unmap_buffer
ext3: quota_write cross block boundary behaviour
quota: drop permission checks from xfs_fs_set_xstate/xfs_fs_set_xquota
quota: split out compat_sys_quotactl support from quota.c
quota: split out netlink notification support from quota.c
quota: remove invalid optimization from quota_sync_all
...
Fixed trivial conflicts in fs/namei.c and fs/ufs/inode.c
Diffstat (limited to 'fs/ext3/super.c')
-rw-r--r-- | fs/ext3/super.c | 246 |
1 files changed, 123 insertions, 123 deletions
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index afa2b569da10..e844accbf55d 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
@@ -181,7 +181,7 @@ static void ext3_handle_error(struct super_block *sb) | |||
181 | if (!test_opt (sb, ERRORS_CONT)) { | 181 | if (!test_opt (sb, ERRORS_CONT)) { |
182 | journal_t *journal = EXT3_SB(sb)->s_journal; | 182 | journal_t *journal = EXT3_SB(sb)->s_journal; |
183 | 183 | ||
184 | EXT3_SB(sb)->s_mount_opt |= EXT3_MOUNT_ABORT; | 184 | set_opt(EXT3_SB(sb)->s_mount_opt, ABORT); |
185 | if (journal) | 185 | if (journal) |
186 | journal_abort(journal, -EIO); | 186 | journal_abort(journal, -EIO); |
187 | } | 187 | } |
@@ -296,7 +296,7 @@ void ext3_abort (struct super_block * sb, const char * function, | |||
296 | "error: remounting filesystem read-only"); | 296 | "error: remounting filesystem read-only"); |
297 | EXT3_SB(sb)->s_mount_state |= EXT3_ERROR_FS; | 297 | EXT3_SB(sb)->s_mount_state |= EXT3_ERROR_FS; |
298 | sb->s_flags |= MS_RDONLY; | 298 | sb->s_flags |= MS_RDONLY; |
299 | EXT3_SB(sb)->s_mount_opt |= EXT3_MOUNT_ABORT; | 299 | set_opt(EXT3_SB(sb)->s_mount_opt, ABORT); |
300 | if (EXT3_SB(sb)->s_journal) | 300 | if (EXT3_SB(sb)->s_journal) |
301 | journal_abort(EXT3_SB(sb)->s_journal, -EIO); | 301 | journal_abort(EXT3_SB(sb)->s_journal, -EIO); |
302 | } | 302 | } |
@@ -528,6 +528,8 @@ static void destroy_inodecache(void) | |||
528 | static void ext3_clear_inode(struct inode *inode) | 528 | static void ext3_clear_inode(struct inode *inode) |
529 | { | 529 | { |
530 | struct ext3_block_alloc_info *rsv = EXT3_I(inode)->i_block_alloc_info; | 530 | struct ext3_block_alloc_info *rsv = EXT3_I(inode)->i_block_alloc_info; |
531 | |||
532 | dquot_drop(inode); | ||
531 | ext3_discard_reservation(inode); | 533 | ext3_discard_reservation(inode); |
532 | EXT3_I(inode)->i_block_alloc_info = NULL; | 534 | EXT3_I(inode)->i_block_alloc_info = NULL; |
533 | if (unlikely(rsv)) | 535 | if (unlikely(rsv)) |
@@ -562,10 +564,10 @@ static inline void ext3_show_quota_options(struct seq_file *seq, struct super_bl | |||
562 | if (sbi->s_qf_names[GRPQUOTA]) | 564 | if (sbi->s_qf_names[GRPQUOTA]) |
563 | seq_printf(seq, ",grpjquota=%s", sbi->s_qf_names[GRPQUOTA]); | 565 | seq_printf(seq, ",grpjquota=%s", sbi->s_qf_names[GRPQUOTA]); |
564 | 566 | ||
565 | if (sbi->s_mount_opt & EXT3_MOUNT_USRQUOTA) | 567 | if (test_opt(sb, USRQUOTA)) |
566 | seq_puts(seq, ",usrquota"); | 568 | seq_puts(seq, ",usrquota"); |
567 | 569 | ||
568 | if (sbi->s_mount_opt & EXT3_MOUNT_GRPQUOTA) | 570 | if (test_opt(sb, GRPQUOTA)) |
569 | seq_puts(seq, ",grpquota"); | 571 | seq_puts(seq, ",grpquota"); |
570 | #endif | 572 | #endif |
571 | } | 573 | } |
@@ -656,8 +658,7 @@ static int ext3_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
656 | if (test_opt(sb, NOBH)) | 658 | if (test_opt(sb, NOBH)) |
657 | seq_puts(seq, ",nobh"); | 659 | seq_puts(seq, ",nobh"); |
658 | 660 | ||
659 | seq_printf(seq, ",data=%s", data_mode_string(sbi->s_mount_opt & | 661 | seq_printf(seq, ",data=%s", data_mode_string(test_opt(sb, DATA_FLAGS))); |
660 | EXT3_MOUNT_DATA_FLAGS)); | ||
661 | if (test_opt(sb, DATA_ERR_ABORT)) | 662 | if (test_opt(sb, DATA_ERR_ABORT)) |
662 | seq_puts(seq, ",data_err=abort"); | 663 | seq_puts(seq, ",data_err=abort"); |
663 | 664 | ||
@@ -751,13 +752,6 @@ static ssize_t ext3_quota_write(struct super_block *sb, int type, | |||
751 | const char *data, size_t len, loff_t off); | 752 | const char *data, size_t len, loff_t off); |
752 | 753 | ||
753 | static const struct dquot_operations ext3_quota_operations = { | 754 | static const struct dquot_operations ext3_quota_operations = { |
754 | .initialize = dquot_initialize, | ||
755 | .drop = dquot_drop, | ||
756 | .alloc_space = dquot_alloc_space, | ||
757 | .alloc_inode = dquot_alloc_inode, | ||
758 | .free_space = dquot_free_space, | ||
759 | .free_inode = dquot_free_inode, | ||
760 | .transfer = dquot_transfer, | ||
761 | .write_dquot = ext3_write_dquot, | 755 | .write_dquot = ext3_write_dquot, |
762 | .acquire_dquot = ext3_acquire_dquot, | 756 | .acquire_dquot = ext3_acquire_dquot, |
763 | .release_dquot = ext3_release_dquot, | 757 | .release_dquot = ext3_release_dquot, |
@@ -896,6 +890,63 @@ static ext3_fsblk_t get_sb_block(void **data, struct super_block *sb) | |||
896 | return sb_block; | 890 | return sb_block; |
897 | } | 891 | } |
898 | 892 | ||
893 | #ifdef CONFIG_QUOTA | ||
894 | static int set_qf_name(struct super_block *sb, int qtype, substring_t *args) | ||
895 | { | ||
896 | struct ext3_sb_info *sbi = EXT3_SB(sb); | ||
897 | char *qname; | ||
898 | |||
899 | if (sb_any_quota_loaded(sb) && | ||
900 | !sbi->s_qf_names[qtype]) { | ||
901 | ext3_msg(sb, KERN_ERR, | ||
902 | "Cannot change journaled " | ||
903 | "quota options when quota turned on"); | ||
904 | return 0; | ||
905 | } | ||
906 | qname = match_strdup(args); | ||
907 | if (!qname) { | ||
908 | ext3_msg(sb, KERN_ERR, | ||
909 | "Not enough memory for storing quotafile name"); | ||
910 | return 0; | ||
911 | } | ||
912 | if (sbi->s_qf_names[qtype] && | ||
913 | strcmp(sbi->s_qf_names[qtype], qname)) { | ||
914 | ext3_msg(sb, KERN_ERR, | ||
915 | "%s quota file already specified", QTYPE2NAME(qtype)); | ||
916 | kfree(qname); | ||
917 | return 0; | ||
918 | } | ||
919 | sbi->s_qf_names[qtype] = qname; | ||
920 | if (strchr(sbi->s_qf_names[qtype], '/')) { | ||
921 | ext3_msg(sb, KERN_ERR, | ||
922 | "quotafile must be on filesystem root"); | ||
923 | kfree(sbi->s_qf_names[qtype]); | ||
924 | sbi->s_qf_names[qtype] = NULL; | ||
925 | return 0; | ||
926 | } | ||
927 | set_opt(sbi->s_mount_opt, QUOTA); | ||
928 | return 1; | ||
929 | } | ||
930 | |||
931 | static int clear_qf_name(struct super_block *sb, int qtype) { | ||
932 | |||
933 | struct ext3_sb_info *sbi = EXT3_SB(sb); | ||
934 | |||
935 | if (sb_any_quota_loaded(sb) && | ||
936 | sbi->s_qf_names[qtype]) { | ||
937 | ext3_msg(sb, KERN_ERR, "Cannot change journaled quota options" | ||
938 | " when quota turned on"); | ||
939 | return 0; | ||
940 | } | ||
941 | /* | ||
942 | * The space will be released later when all options are confirmed | ||
943 | * to be correct | ||
944 | */ | ||
945 | sbi->s_qf_names[qtype] = NULL; | ||
946 | return 1; | ||
947 | } | ||
948 | #endif | ||
949 | |||
899 | static int parse_options (char *options, struct super_block *sb, | 950 | static int parse_options (char *options, struct super_block *sb, |
900 | unsigned int *inum, unsigned long *journal_devnum, | 951 | unsigned int *inum, unsigned long *journal_devnum, |
901 | ext3_fsblk_t *n_blocks_count, int is_remount) | 952 | ext3_fsblk_t *n_blocks_count, int is_remount) |
@@ -906,8 +957,7 @@ static int parse_options (char *options, struct super_block *sb, | |||
906 | int data_opt = 0; | 957 | int data_opt = 0; |
907 | int option; | 958 | int option; |
908 | #ifdef CONFIG_QUOTA | 959 | #ifdef CONFIG_QUOTA |
909 | int qtype, qfmt; | 960 | int qfmt; |
910 | char *qname; | ||
911 | #endif | 961 | #endif |
912 | 962 | ||
913 | if (!options) | 963 | if (!options) |
@@ -1065,20 +1115,19 @@ static int parse_options (char *options, struct super_block *sb, | |||
1065 | data_opt = EXT3_MOUNT_WRITEBACK_DATA; | 1115 | data_opt = EXT3_MOUNT_WRITEBACK_DATA; |
1066 | datacheck: | 1116 | datacheck: |
1067 | if (is_remount) { | 1117 | if (is_remount) { |
1068 | if ((sbi->s_mount_opt & EXT3_MOUNT_DATA_FLAGS) | 1118 | if (test_opt(sb, DATA_FLAGS) == data_opt) |
1069 | == data_opt) | ||
1070 | break; | 1119 | break; |
1071 | ext3_msg(sb, KERN_ERR, | 1120 | ext3_msg(sb, KERN_ERR, |
1072 | "error: cannot change " | 1121 | "error: cannot change " |
1073 | "data mode on remount. The filesystem " | 1122 | "data mode on remount. The filesystem " |
1074 | "is mounted in data=%s mode and you " | 1123 | "is mounted in data=%s mode and you " |
1075 | "try to remount it in data=%s mode.", | 1124 | "try to remount it in data=%s mode.", |
1076 | data_mode_string(sbi->s_mount_opt & | 1125 | data_mode_string(test_opt(sb, |
1077 | EXT3_MOUNT_DATA_FLAGS), | 1126 | DATA_FLAGS)), |
1078 | data_mode_string(data_opt)); | 1127 | data_mode_string(data_opt)); |
1079 | return 0; | 1128 | return 0; |
1080 | } else { | 1129 | } else { |
1081 | sbi->s_mount_opt &= ~EXT3_MOUNT_DATA_FLAGS; | 1130 | clear_opt(sbi->s_mount_opt, DATA_FLAGS); |
1082 | sbi->s_mount_opt |= data_opt; | 1131 | sbi->s_mount_opt |= data_opt; |
1083 | } | 1132 | } |
1084 | break; | 1133 | break; |
@@ -1090,62 +1139,20 @@ static int parse_options (char *options, struct super_block *sb, | |||
1090 | break; | 1139 | break; |
1091 | #ifdef CONFIG_QUOTA | 1140 | #ifdef CONFIG_QUOTA |
1092 | case Opt_usrjquota: | 1141 | case Opt_usrjquota: |
1093 | qtype = USRQUOTA; | 1142 | if (!set_qf_name(sb, USRQUOTA, &args[0])) |
1094 | goto set_qf_name; | ||
1095 | case Opt_grpjquota: | ||
1096 | qtype = GRPQUOTA; | ||
1097 | set_qf_name: | ||
1098 | if (sb_any_quota_loaded(sb) && | ||
1099 | !sbi->s_qf_names[qtype]) { | ||
1100 | ext3_msg(sb, KERN_ERR, | ||
1101 | "error: cannot change journaled " | ||
1102 | "quota options when quota turned on."); | ||
1103 | return 0; | ||
1104 | } | ||
1105 | qname = match_strdup(&args[0]); | ||
1106 | if (!qname) { | ||
1107 | ext3_msg(sb, KERN_ERR, | ||
1108 | "error: not enough memory for " | ||
1109 | "storing quotafile name."); | ||
1110 | return 0; | 1143 | return 0; |
1111 | } | 1144 | break; |
1112 | if (sbi->s_qf_names[qtype] && | 1145 | case Opt_grpjquota: |
1113 | strcmp(sbi->s_qf_names[qtype], qname)) { | 1146 | if (!set_qf_name(sb, GRPQUOTA, &args[0])) |
1114 | ext3_msg(sb, KERN_ERR, | ||
1115 | "error: %s quota file already " | ||
1116 | "specified.", QTYPE2NAME(qtype)); | ||
1117 | kfree(qname); | ||
1118 | return 0; | ||
1119 | } | ||
1120 | sbi->s_qf_names[qtype] = qname; | ||
1121 | if (strchr(sbi->s_qf_names[qtype], '/')) { | ||
1122 | ext3_msg(sb, KERN_ERR, | ||
1123 | "error: quotafile must be on " | ||
1124 | "filesystem root."); | ||
1125 | kfree(sbi->s_qf_names[qtype]); | ||
1126 | sbi->s_qf_names[qtype] = NULL; | ||
1127 | return 0; | 1147 | return 0; |
1128 | } | ||
1129 | set_opt(sbi->s_mount_opt, QUOTA); | ||
1130 | break; | 1148 | break; |
1131 | case Opt_offusrjquota: | 1149 | case Opt_offusrjquota: |
1132 | qtype = USRQUOTA; | 1150 | if (!clear_qf_name(sb, USRQUOTA)) |
1133 | goto clear_qf_name; | 1151 | return 0; |
1152 | break; | ||
1134 | case Opt_offgrpjquota: | 1153 | case Opt_offgrpjquota: |
1135 | qtype = GRPQUOTA; | 1154 | if (!clear_qf_name(sb, GRPQUOTA)) |
1136 | clear_qf_name: | ||
1137 | if (sb_any_quota_loaded(sb) && | ||
1138 | sbi->s_qf_names[qtype]) { | ||
1139 | ext3_msg(sb, KERN_ERR, "error: cannot change " | ||
1140 | "journaled quota options when " | ||
1141 | "quota turned on."); | ||
1142 | return 0; | 1155 | return 0; |
1143 | } | ||
1144 | /* | ||
1145 | * The space will be released later when all options | ||
1146 | * are confirmed to be correct | ||
1147 | */ | ||
1148 | sbi->s_qf_names[qtype] = NULL; | ||
1149 | break; | 1156 | break; |
1150 | case Opt_jqfmt_vfsold: | 1157 | case Opt_jqfmt_vfsold: |
1151 | qfmt = QFMT_VFS_OLD; | 1158 | qfmt = QFMT_VFS_OLD; |
@@ -1244,18 +1251,12 @@ set_qf_format: | |||
1244 | } | 1251 | } |
1245 | #ifdef CONFIG_QUOTA | 1252 | #ifdef CONFIG_QUOTA |
1246 | if (sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA]) { | 1253 | if (sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA]) { |
1247 | if ((sbi->s_mount_opt & EXT3_MOUNT_USRQUOTA) && | 1254 | if (test_opt(sb, USRQUOTA) && sbi->s_qf_names[USRQUOTA]) |
1248 | sbi->s_qf_names[USRQUOTA]) | ||
1249 | clear_opt(sbi->s_mount_opt, USRQUOTA); | 1255 | clear_opt(sbi->s_mount_opt, USRQUOTA); |
1250 | 1256 | if (test_opt(sb, GRPQUOTA) && sbi->s_qf_names[GRPQUOTA]) | |
1251 | if ((sbi->s_mount_opt & EXT3_MOUNT_GRPQUOTA) && | ||
1252 | sbi->s_qf_names[GRPQUOTA]) | ||
1253 | clear_opt(sbi->s_mount_opt, GRPQUOTA); | 1257 | clear_opt(sbi->s_mount_opt, GRPQUOTA); |
1254 | 1258 | ||
1255 | if ((sbi->s_qf_names[USRQUOTA] && | 1259 | if (test_opt(sb, GRPQUOTA) || test_opt(sb, USRQUOTA)) { |
1256 | (sbi->s_mount_opt & EXT3_MOUNT_GRPQUOTA)) || | ||
1257 | (sbi->s_qf_names[GRPQUOTA] && | ||
1258 | (sbi->s_mount_opt & EXT3_MOUNT_USRQUOTA))) { | ||
1259 | ext3_msg(sb, KERN_ERR, "error: old and new quota " | 1260 | ext3_msg(sb, KERN_ERR, "error: old and new quota " |
1260 | "format mixing."); | 1261 | "format mixing."); |
1261 | return 0; | 1262 | return 0; |
@@ -1478,7 +1479,7 @@ static void ext3_orphan_cleanup (struct super_block * sb, | |||
1478 | } | 1479 | } |
1479 | 1480 | ||
1480 | list_add(&EXT3_I(inode)->i_orphan, &EXT3_SB(sb)->s_orphan); | 1481 | list_add(&EXT3_I(inode)->i_orphan, &EXT3_SB(sb)->s_orphan); |
1481 | vfs_dq_init(inode); | 1482 | dquot_initialize(inode); |
1482 | if (inode->i_nlink) { | 1483 | if (inode->i_nlink) { |
1483 | printk(KERN_DEBUG | 1484 | printk(KERN_DEBUG |
1484 | "%s: truncating inode %lu to %Ld bytes\n", | 1485 | "%s: truncating inode %lu to %Ld bytes\n", |
@@ -1671,11 +1672,11 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent) | |||
1671 | set_opt(sbi->s_mount_opt, POSIX_ACL); | 1672 | set_opt(sbi->s_mount_opt, POSIX_ACL); |
1672 | #endif | 1673 | #endif |
1673 | if ((def_mount_opts & EXT3_DEFM_JMODE) == EXT3_DEFM_JMODE_DATA) | 1674 | if ((def_mount_opts & EXT3_DEFM_JMODE) == EXT3_DEFM_JMODE_DATA) |
1674 | sbi->s_mount_opt |= EXT3_MOUNT_JOURNAL_DATA; | 1675 | set_opt(sbi->s_mount_opt, JOURNAL_DATA); |
1675 | else if ((def_mount_opts & EXT3_DEFM_JMODE) == EXT3_DEFM_JMODE_ORDERED) | 1676 | else if ((def_mount_opts & EXT3_DEFM_JMODE) == EXT3_DEFM_JMODE_ORDERED) |
1676 | sbi->s_mount_opt |= EXT3_MOUNT_ORDERED_DATA; | 1677 | set_opt(sbi->s_mount_opt, ORDERED_DATA); |
1677 | else if ((def_mount_opts & EXT3_DEFM_JMODE) == EXT3_DEFM_JMODE_WBACK) | 1678 | else if ((def_mount_opts & EXT3_DEFM_JMODE) == EXT3_DEFM_JMODE_WBACK) |
1678 | sbi->s_mount_opt |= EXT3_MOUNT_WRITEBACK_DATA; | 1679 | set_opt(sbi->s_mount_opt, WRITEBACK_DATA); |
1679 | 1680 | ||
1680 | if (le16_to_cpu(sbi->s_es->s_errors) == EXT3_ERRORS_PANIC) | 1681 | if (le16_to_cpu(sbi->s_es->s_errors) == EXT3_ERRORS_PANIC) |
1681 | set_opt(sbi->s_mount_opt, ERRORS_PANIC); | 1682 | set_opt(sbi->s_mount_opt, ERRORS_PANIC); |
@@ -1694,7 +1695,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent) | |||
1694 | goto failed_mount; | 1695 | goto failed_mount; |
1695 | 1696 | ||
1696 | sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | | 1697 | sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | |
1697 | ((sbi->s_mount_opt & EXT3_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0); | 1698 | (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0); |
1698 | 1699 | ||
1699 | if (le32_to_cpu(es->s_rev_level) == EXT3_GOOD_OLD_REV && | 1700 | if (le32_to_cpu(es->s_rev_level) == EXT3_GOOD_OLD_REV && |
1700 | (EXT3_HAS_COMPAT_FEATURE(sb, ~0U) || | 1701 | (EXT3_HAS_COMPAT_FEATURE(sb, ~0U) || |
@@ -2561,11 +2562,11 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data) | |||
2561 | goto restore_opts; | 2562 | goto restore_opts; |
2562 | } | 2563 | } |
2563 | 2564 | ||
2564 | if (sbi->s_mount_opt & EXT3_MOUNT_ABORT) | 2565 | if (test_opt(sb, ABORT)) |
2565 | ext3_abort(sb, __func__, "Abort forced by user"); | 2566 | ext3_abort(sb, __func__, "Abort forced by user"); |
2566 | 2567 | ||
2567 | sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | | 2568 | sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | |
2568 | ((sbi->s_mount_opt & EXT3_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0); | 2569 | (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0); |
2569 | 2570 | ||
2570 | es = sbi->s_es; | 2571 | es = sbi->s_es; |
2571 | 2572 | ||
@@ -2573,7 +2574,7 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data) | |||
2573 | 2574 | ||
2574 | if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY) || | 2575 | if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY) || |
2575 | n_blocks_count > le32_to_cpu(es->s_blocks_count)) { | 2576 | n_blocks_count > le32_to_cpu(es->s_blocks_count)) { |
2576 | if (sbi->s_mount_opt & EXT3_MOUNT_ABORT) { | 2577 | if (test_opt(sb, ABORT)) { |
2577 | err = -EROFS; | 2578 | err = -EROFS; |
2578 | goto restore_opts; | 2579 | goto restore_opts; |
2579 | } | 2580 | } |
@@ -2734,7 +2735,7 @@ static int ext3_statfs (struct dentry * dentry, struct kstatfs * buf) | |||
2734 | * Process 1 Process 2 | 2735 | * Process 1 Process 2 |
2735 | * ext3_create() quota_sync() | 2736 | * ext3_create() quota_sync() |
2736 | * journal_start() write_dquot() | 2737 | * journal_start() write_dquot() |
2737 | * vfs_dq_init() down(dqio_mutex) | 2738 | * dquot_initialize() down(dqio_mutex) |
2738 | * down(dqio_mutex) journal_start() | 2739 | * down(dqio_mutex) journal_start() |
2739 | * | 2740 | * |
2740 | */ | 2741 | */ |
@@ -2942,9 +2943,7 @@ static ssize_t ext3_quota_write(struct super_block *sb, int type, | |||
2942 | sector_t blk = off >> EXT3_BLOCK_SIZE_BITS(sb); | 2943 | sector_t blk = off >> EXT3_BLOCK_SIZE_BITS(sb); |
2943 | int err = 0; | 2944 | int err = 0; |
2944 | int offset = off & (sb->s_blocksize - 1); | 2945 | int offset = off & (sb->s_blocksize - 1); |
2945 | int tocopy; | ||
2946 | int journal_quota = EXT3_SB(sb)->s_qf_names[type] != NULL; | 2946 | int journal_quota = EXT3_SB(sb)->s_qf_names[type] != NULL; |
2947 | size_t towrite = len; | ||
2948 | struct buffer_head *bh; | 2947 | struct buffer_head *bh; |
2949 | handle_t *handle = journal_current_handle(); | 2948 | handle_t *handle = journal_current_handle(); |
2950 | 2949 | ||
@@ -2955,53 +2954,54 @@ static ssize_t ext3_quota_write(struct super_block *sb, int type, | |||
2955 | (unsigned long long)off, (unsigned long long)len); | 2954 | (unsigned long long)off, (unsigned long long)len); |
2956 | return -EIO; | 2955 | return -EIO; |
2957 | } | 2956 | } |
2957 | |||
2958 | /* | ||
2959 | * Since we account only one data block in transaction credits, | ||
2960 | * then it is impossible to cross a block boundary. | ||
2961 | */ | ||
2962 | if (sb->s_blocksize - offset < len) { | ||
2963 | ext3_msg(sb, KERN_WARNING, "Quota write (off=%llu, len=%llu)" | ||
2964 | " cancelled because not block aligned", | ||
2965 | (unsigned long long)off, (unsigned long long)len); | ||
2966 | return -EIO; | ||
2967 | } | ||
2958 | mutex_lock_nested(&inode->i_mutex, I_MUTEX_QUOTA); | 2968 | mutex_lock_nested(&inode->i_mutex, I_MUTEX_QUOTA); |
2959 | while (towrite > 0) { | 2969 | bh = ext3_bread(handle, inode, blk, 1, &err); |
2960 | tocopy = sb->s_blocksize - offset < towrite ? | 2970 | if (!bh) |
2961 | sb->s_blocksize - offset : towrite; | 2971 | goto out; |
2962 | bh = ext3_bread(handle, inode, blk, 1, &err); | 2972 | if (journal_quota) { |
2963 | if (!bh) | 2973 | err = ext3_journal_get_write_access(handle, bh); |
2974 | if (err) { | ||
2975 | brelse(bh); | ||
2964 | goto out; | 2976 | goto out; |
2965 | if (journal_quota) { | ||
2966 | err = ext3_journal_get_write_access(handle, bh); | ||
2967 | if (err) { | ||
2968 | brelse(bh); | ||
2969 | goto out; | ||
2970 | } | ||
2971 | } | ||
2972 | lock_buffer(bh); | ||
2973 | memcpy(bh->b_data+offset, data, tocopy); | ||
2974 | flush_dcache_page(bh->b_page); | ||
2975 | unlock_buffer(bh); | ||
2976 | if (journal_quota) | ||
2977 | err = ext3_journal_dirty_metadata(handle, bh); | ||
2978 | else { | ||
2979 | /* Always do at least ordered writes for quotas */ | ||
2980 | err = ext3_journal_dirty_data(handle, bh); | ||
2981 | mark_buffer_dirty(bh); | ||
2982 | } | 2977 | } |
2983 | brelse(bh); | ||
2984 | if (err) | ||
2985 | goto out; | ||
2986 | offset = 0; | ||
2987 | towrite -= tocopy; | ||
2988 | data += tocopy; | ||
2989 | blk++; | ||
2990 | } | 2978 | } |
2979 | lock_buffer(bh); | ||
2980 | memcpy(bh->b_data+offset, data, len); | ||
2981 | flush_dcache_page(bh->b_page); | ||
2982 | unlock_buffer(bh); | ||
2983 | if (journal_quota) | ||
2984 | err = ext3_journal_dirty_metadata(handle, bh); | ||
2985 | else { | ||
2986 | /* Always do at least ordered writes for quotas */ | ||
2987 | err = ext3_journal_dirty_data(handle, bh); | ||
2988 | mark_buffer_dirty(bh); | ||
2989 | } | ||
2990 | brelse(bh); | ||
2991 | out: | 2991 | out: |
2992 | if (len == towrite) { | 2992 | if (err) { |
2993 | mutex_unlock(&inode->i_mutex); | 2993 | mutex_unlock(&inode->i_mutex); |
2994 | return err; | 2994 | return err; |
2995 | } | 2995 | } |
2996 | if (inode->i_size < off+len-towrite) { | 2996 | if (inode->i_size < off + len) { |
2997 | i_size_write(inode, off+len-towrite); | 2997 | i_size_write(inode, off + len); |
2998 | EXT3_I(inode)->i_disksize = inode->i_size; | 2998 | EXT3_I(inode)->i_disksize = inode->i_size; |
2999 | } | 2999 | } |
3000 | inode->i_version++; | 3000 | inode->i_version++; |
3001 | inode->i_mtime = inode->i_ctime = CURRENT_TIME; | 3001 | inode->i_mtime = inode->i_ctime = CURRENT_TIME; |
3002 | ext3_mark_inode_dirty(handle, inode); | 3002 | ext3_mark_inode_dirty(handle, inode); |
3003 | mutex_unlock(&inode->i_mutex); | 3003 | mutex_unlock(&inode->i_mutex); |
3004 | return len - towrite; | 3004 | return len; |
3005 | } | 3005 | } |
3006 | 3006 | ||
3007 | #endif | 3007 | #endif |