aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ext4/inline.c5
-rw-r--r--fs/ext4/inode.c2
-rw-r--r--fs/ext4/move_extent.c2
-rw-r--r--fs/ext4/xattr.c65
-rw-r--r--fs/jbd2/journal.c22
-rw-r--r--fs/jbd2/revoke.c1
6 files changed, 47 insertions, 50 deletions
diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c
index 30a9f210d1e3..375fb1c05d49 100644
--- a/fs/ext4/inline.c
+++ b/fs/ext4/inline.c
@@ -1169,10 +1169,9 @@ static int ext4_finish_convert_inline_dir(handle_t *handle,
1169 set_buffer_uptodate(dir_block); 1169 set_buffer_uptodate(dir_block);
1170 err = ext4_handle_dirty_dirent_node(handle, inode, dir_block); 1170 err = ext4_handle_dirty_dirent_node(handle, inode, dir_block);
1171 if (err) 1171 if (err)
1172 goto out; 1172 return err;
1173 set_buffer_verified(dir_block); 1173 set_buffer_verified(dir_block);
1174out: 1174 return ext4_mark_inode_dirty(handle, inode);
1175 return err;
1176} 1175}
1177 1176
1178static int ext4_convert_inline_data_nolock(handle_t *handle, 1177static int ext4_convert_inline_data_nolock(handle_t *handle,
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 7385e6a6b6cb..4247d8d25687 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -5400,7 +5400,7 @@ int ext4_getattr(const struct path *path, struct kstat *stat,
5400 * If there is inline data in the inode, the inode will normally not 5400 * If there is inline data in the inode, the inode will normally not
5401 * have data blocks allocated (it may have an external xattr block). 5401 * have data blocks allocated (it may have an external xattr block).
5402 * Report at least one sector for such files, so tools like tar, rsync, 5402 * Report at least one sector for such files, so tools like tar, rsync,
5403 * others doen't incorrectly think the file is completely sparse. 5403 * others don't incorrectly think the file is completely sparse.
5404 */ 5404 */
5405 if (unlikely(ext4_has_inline_data(inode))) 5405 if (unlikely(ext4_has_inline_data(inode)))
5406 stat->blocks += (stat->size + 511) >> 9; 5406 stat->blocks += (stat->size + 511) >> 9;
diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c
index 578f8c33fb44..c992ef2c2f94 100644
--- a/fs/ext4/move_extent.c
+++ b/fs/ext4/move_extent.c
@@ -511,7 +511,7 @@ mext_check_arguments(struct inode *orig_inode,
511 if ((orig_start & ~(PAGE_MASK >> orig_inode->i_blkbits)) != 511 if ((orig_start & ~(PAGE_MASK >> orig_inode->i_blkbits)) !=
512 (donor_start & ~(PAGE_MASK >> orig_inode->i_blkbits))) { 512 (donor_start & ~(PAGE_MASK >> orig_inode->i_blkbits))) {
513 ext4_debug("ext4 move extent: orig and donor's start " 513 ext4_debug("ext4 move extent: orig and donor's start "
514 "offset are not alligned [ino:orig %lu, donor %lu]\n", 514 "offsets are not aligned [ino:orig %lu, donor %lu]\n",
515 orig_inode->i_ino, donor_inode->i_ino); 515 orig_inode->i_ino, donor_inode->i_ino);
516 return -EINVAL; 516 return -EINVAL;
517 } 517 }
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
index 67636acf7624..996e7900d4c8 100644
--- a/fs/ext4/xattr.c
+++ b/fs/ext4/xattr.c
@@ -131,31 +131,26 @@ static __le32 ext4_xattr_block_csum(struct inode *inode,
131} 131}
132 132
133static int ext4_xattr_block_csum_verify(struct inode *inode, 133static int ext4_xattr_block_csum_verify(struct inode *inode,
134 sector_t block_nr, 134 struct buffer_head *bh)
135 struct ext4_xattr_header *hdr)
136{ 135{
137 if (ext4_has_metadata_csum(inode->i_sb) && 136 struct ext4_xattr_header *hdr = BHDR(bh);
138 (hdr->h_checksum != ext4_xattr_block_csum(inode, block_nr, hdr))) 137 int ret = 1;
139 return 0;
140 return 1;
141}
142
143static void ext4_xattr_block_csum_set(struct inode *inode,
144 sector_t block_nr,
145 struct ext4_xattr_header *hdr)
146{
147 if (!ext4_has_metadata_csum(inode->i_sb))
148 return;
149 138
150 hdr->h_checksum = ext4_xattr_block_csum(inode, block_nr, hdr); 139 if (ext4_has_metadata_csum(inode->i_sb)) {
140 lock_buffer(bh);
141 ret = (hdr->h_checksum == ext4_xattr_block_csum(inode,
142 bh->b_blocknr, hdr));
143 unlock_buffer(bh);
144 }
145 return ret;
151} 146}
152 147
153static inline int ext4_handle_dirty_xattr_block(handle_t *handle, 148static void ext4_xattr_block_csum_set(struct inode *inode,
154 struct inode *inode, 149 struct buffer_head *bh)
155 struct buffer_head *bh)
156{ 150{
157 ext4_xattr_block_csum_set(inode, bh->b_blocknr, BHDR(bh)); 151 if (ext4_has_metadata_csum(inode->i_sb))
158 return ext4_handle_dirty_metadata(handle, inode, bh); 152 BHDR(bh)->h_checksum = ext4_xattr_block_csum(inode,
153 bh->b_blocknr, BHDR(bh));
159} 154}
160 155
161static inline const struct xattr_handler * 156static inline const struct xattr_handler *
@@ -233,7 +228,7 @@ ext4_xattr_check_block(struct inode *inode, struct buffer_head *bh)
233 if (BHDR(bh)->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC) || 228 if (BHDR(bh)->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC) ||
234 BHDR(bh)->h_blocks != cpu_to_le32(1)) 229 BHDR(bh)->h_blocks != cpu_to_le32(1))
235 return -EFSCORRUPTED; 230 return -EFSCORRUPTED;
236 if (!ext4_xattr_block_csum_verify(inode, bh->b_blocknr, BHDR(bh))) 231 if (!ext4_xattr_block_csum_verify(inode, bh))
237 return -EFSBADCRC; 232 return -EFSBADCRC;
238 error = ext4_xattr_check_names(BFIRST(bh), bh->b_data + bh->b_size, 233 error = ext4_xattr_check_names(BFIRST(bh), bh->b_data + bh->b_size,
239 bh->b_data); 234 bh->b_data);
@@ -618,23 +613,22 @@ ext4_xattr_release_block(handle_t *handle, struct inode *inode,
618 } 613 }
619 } 614 }
620 615
616 ext4_xattr_block_csum_set(inode, bh);
621 /* 617 /*
622 * Beware of this ugliness: Releasing of xattr block references 618 * Beware of this ugliness: Releasing of xattr block references
623 * from different inodes can race and so we have to protect 619 * from different inodes can race and so we have to protect
624 * from a race where someone else frees the block (and releases 620 * from a race where someone else frees the block (and releases
625 * its journal_head) before we are done dirtying the buffer. In 621 * its journal_head) before we are done dirtying the buffer. In
626 * nojournal mode this race is harmless and we actually cannot 622 * nojournal mode this race is harmless and we actually cannot
627 * call ext4_handle_dirty_xattr_block() with locked buffer as 623 * call ext4_handle_dirty_metadata() with locked buffer as
628 * that function can call sync_dirty_buffer() so for that case 624 * that function can call sync_dirty_buffer() so for that case
629 * we handle the dirtying after unlocking the buffer. 625 * we handle the dirtying after unlocking the buffer.
630 */ 626 */
631 if (ext4_handle_valid(handle)) 627 if (ext4_handle_valid(handle))
632 error = ext4_handle_dirty_xattr_block(handle, inode, 628 error = ext4_handle_dirty_metadata(handle, inode, bh);
633 bh);
634 unlock_buffer(bh); 629 unlock_buffer(bh);
635 if (!ext4_handle_valid(handle)) 630 if (!ext4_handle_valid(handle))
636 error = ext4_handle_dirty_xattr_block(handle, inode, 631 error = ext4_handle_dirty_metadata(handle, inode, bh);
637 bh);
638 if (IS_SYNC(inode)) 632 if (IS_SYNC(inode))
639 ext4_handle_sync(handle); 633 ext4_handle_sync(handle);
640 dquot_free_block(inode, EXT4_C2B(EXT4_SB(inode->i_sb), 1)); 634 dquot_free_block(inode, EXT4_C2B(EXT4_SB(inode->i_sb), 1));
@@ -863,13 +857,14 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,
863 ext4_xattr_cache_insert(ext4_mb_cache, 857 ext4_xattr_cache_insert(ext4_mb_cache,
864 bs->bh); 858 bs->bh);
865 } 859 }
860 ext4_xattr_block_csum_set(inode, bs->bh);
866 unlock_buffer(bs->bh); 861 unlock_buffer(bs->bh);
867 if (error == -EFSCORRUPTED) 862 if (error == -EFSCORRUPTED)
868 goto bad_block; 863 goto bad_block;
869 if (!error) 864 if (!error)
870 error = ext4_handle_dirty_xattr_block(handle, 865 error = ext4_handle_dirty_metadata(handle,
871 inode, 866 inode,
872 bs->bh); 867 bs->bh);
873 if (error) 868 if (error)
874 goto cleanup; 869 goto cleanup;
875 goto inserted; 870 goto inserted;
@@ -967,10 +962,11 @@ inserted:
967 ce->e_reusable = 0; 962 ce->e_reusable = 0;
968 ea_bdebug(new_bh, "reusing; refcount now=%d", 963 ea_bdebug(new_bh, "reusing; refcount now=%d",
969 ref); 964 ref);
965 ext4_xattr_block_csum_set(inode, new_bh);
970 unlock_buffer(new_bh); 966 unlock_buffer(new_bh);
971 error = ext4_handle_dirty_xattr_block(handle, 967 error = ext4_handle_dirty_metadata(handle,
972 inode, 968 inode,
973 new_bh); 969 new_bh);
974 if (error) 970 if (error)
975 goto cleanup_dquot; 971 goto cleanup_dquot;
976 } 972 }
@@ -1020,11 +1016,12 @@ getblk_failed:
1020 goto getblk_failed; 1016 goto getblk_failed;
1021 } 1017 }
1022 memcpy(new_bh->b_data, s->base, new_bh->b_size); 1018 memcpy(new_bh->b_data, s->base, new_bh->b_size);
1019 ext4_xattr_block_csum_set(inode, new_bh);
1023 set_buffer_uptodate(new_bh); 1020 set_buffer_uptodate(new_bh);
1024 unlock_buffer(new_bh); 1021 unlock_buffer(new_bh);
1025 ext4_xattr_cache_insert(ext4_mb_cache, new_bh); 1022 ext4_xattr_cache_insert(ext4_mb_cache, new_bh);
1026 error = ext4_handle_dirty_xattr_block(handle, 1023 error = ext4_handle_dirty_metadata(handle, inode,
1027 inode, new_bh); 1024 new_bh);
1028 if (error) 1025 if (error)
1029 goto cleanup; 1026 goto cleanup;
1030 } 1027 }
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index a1a359bfcc9c..5adc2fb62b0f 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -1125,10 +1125,8 @@ static journal_t *journal_init_common(struct block_device *bdev,
1125 1125
1126 /* Set up a default-sized revoke table for the new mount. */ 1126 /* Set up a default-sized revoke table for the new mount. */
1127 err = jbd2_journal_init_revoke(journal, JOURNAL_REVOKE_DEFAULT_HASH); 1127 err = jbd2_journal_init_revoke(journal, JOURNAL_REVOKE_DEFAULT_HASH);
1128 if (err) { 1128 if (err)
1129 kfree(journal); 1129 goto err_cleanup;
1130 return NULL;
1131 }
1132 1130
1133 spin_lock_init(&journal->j_history_lock); 1131 spin_lock_init(&journal->j_history_lock);
1134 1132
@@ -1145,23 +1143,25 @@ static journal_t *journal_init_common(struct block_device *bdev,
1145 journal->j_wbufsize = n; 1143 journal->j_wbufsize = n;
1146 journal->j_wbuf = kmalloc_array(n, sizeof(struct buffer_head *), 1144 journal->j_wbuf = kmalloc_array(n, sizeof(struct buffer_head *),
1147 GFP_KERNEL); 1145 GFP_KERNEL);
1148 if (!journal->j_wbuf) { 1146 if (!journal->j_wbuf)
1149 kfree(journal); 1147 goto err_cleanup;
1150 return NULL;
1151 }
1152 1148
1153 bh = getblk_unmovable(journal->j_dev, start, journal->j_blocksize); 1149 bh = getblk_unmovable(journal->j_dev, start, journal->j_blocksize);
1154 if (!bh) { 1150 if (!bh) {
1155 pr_err("%s: Cannot get buffer for journal superblock\n", 1151 pr_err("%s: Cannot get buffer for journal superblock\n",
1156 __func__); 1152 __func__);
1157 kfree(journal->j_wbuf); 1153 goto err_cleanup;
1158 kfree(journal);
1159 return NULL;
1160 } 1154 }
1161 journal->j_sb_buffer = bh; 1155 journal->j_sb_buffer = bh;
1162 journal->j_superblock = (journal_superblock_t *)bh->b_data; 1156 journal->j_superblock = (journal_superblock_t *)bh->b_data;
1163 1157
1164 return journal; 1158 return journal;
1159
1160err_cleanup:
1161 kfree(journal->j_wbuf);
1162 jbd2_journal_destroy_revoke(journal);
1163 kfree(journal);
1164 return NULL;
1165} 1165}
1166 1166
1167/* jbd2_journal_init_dev and jbd2_journal_init_inode: 1167/* jbd2_journal_init_dev and jbd2_journal_init_inode:
diff --git a/fs/jbd2/revoke.c b/fs/jbd2/revoke.c
index cfc38b552118..f9aefcda5854 100644
--- a/fs/jbd2/revoke.c
+++ b/fs/jbd2/revoke.c
@@ -280,6 +280,7 @@ int jbd2_journal_init_revoke(journal_t *journal, int hash_size)
280 280
281fail1: 281fail1:
282 jbd2_journal_destroy_revoke_table(journal->j_revoke_table[0]); 282 jbd2_journal_destroy_revoke_table(journal->j_revoke_table[0]);
283 journal->j_revoke_table[0] = NULL;
283fail0: 284fail0:
284 return -ENOMEM; 285 return -ENOMEM;
285} 286}