aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext3/super.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-03-05 16:20:53 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2010-03-05 16:20:53 -0500
commite213e26ab3988c516c06eba4dcd030ac052f6dc9 (patch)
tree6e26fbdbb842b387697d73daf6e70cf718269a77 /fs/ext3/super.c
parentc812a51d11bbe983f4c24e32b59b265705ddd3c2 (diff)
parentefd8f0e6f6c1faa041f228d7113bd3a9db802d49 (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.c246
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)
528static void ext3_clear_inode(struct inode *inode) 528static 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
753static const struct dquot_operations ext3_quota_operations = { 754static 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
894static 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
931static 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
899static int parse_options (char *options, struct super_block *sb, 950static 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;
1097set_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))
1136clear_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);
2991out: 2991out:
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