diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-12-27 20:09:41 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-12-27 20:09:41 -0500 |
commit | f6b1495fba0b66cfa05efa0ca2370513b79b45b6 (patch) | |
tree | 0718aab1784d4a65474404029e72ab288531462a /fs | |
parent | bc77789a491cdc6f47e5bbd1d04ddd283d64658b (diff) | |
parent | 18f2c4fcebf2582f96cbd5f2238f4f354a0e4847 (diff) |
Merge tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
Pull ext4 updates from Ted Ts'o:
"All cleanups and bug fixes; most notably, fix some problems discovered
in ext4's NFS support, and fix an ioctl (EXT4_IOC_GROUP_ADD) used by
old versions of e2fsprogs which we accidentally broke a while back.
Also fixed some error paths in ext4's quota and inline data support.
Finally, improve tail latency in jbd2's commit code"
* tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4:
ext4: check for shutdown and r/o file system in ext4_write_inode()
ext4: force inode writes when nfsd calls commit_metadata()
ext4: avoid declaring fs inconsistent due to invalid file handles
ext4: include terminating u32 in size of xattr entries when expanding inodes
ext4: compare old and new mode before setting update_mode flag
ext4: fix EXT4_IOC_GROUP_ADD ioctl
ext4: hard fail dax mount on unsupported devices
jbd2: update locking documentation for transaction_t
ext4: remove redundant condition check
jbd2: clean up indentation issue, replace spaces with tab
ext4: clean up indentation issues, remove extraneous tabs
ext4: missing unlock/put_page() in ext4_try_to_write_inline_data()
ext4: fix possible use after free in ext4_quota_enable
jbd2: avoid long hold times of j_state_lock while committing a transaction
ext4: add ext4_sb_bread() to disambiguate ENOMEM cases
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ext4/acl.c | 3 | ||||
-rw-r--r-- | fs/ext4/ext4.h | 17 | ||||
-rw-r--r-- | fs/ext4/ialloc.c | 2 | ||||
-rw-r--r-- | fs/ext4/inline.c | 5 | ||||
-rw-r--r-- | fs/ext4/inode.c | 63 | ||||
-rw-r--r-- | fs/ext4/ioctl.c | 2 | ||||
-rw-r--r-- | fs/ext4/migrate.c | 48 | ||||
-rw-r--r-- | fs/ext4/namei.c | 4 | ||||
-rw-r--r-- | fs/ext4/resize.c | 79 | ||||
-rw-r--r-- | fs/ext4/super.c | 92 | ||||
-rw-r--r-- | fs/ext4/xattr.c | 83 | ||||
-rw-r--r-- | fs/jbd2/commit.c | 3 | ||||
-rw-r--r-- | fs/jbd2/transaction.c | 45 |
13 files changed, 272 insertions, 174 deletions
diff --git a/fs/ext4/acl.c b/fs/ext4/acl.c index c1d570ee1d9f..8c7bbf3e566d 100644 --- a/fs/ext4/acl.c +++ b/fs/ext4/acl.c | |||
@@ -248,7 +248,8 @@ retry: | |||
248 | error = posix_acl_update_mode(inode, &mode, &acl); | 248 | error = posix_acl_update_mode(inode, &mode, &acl); |
249 | if (error) | 249 | if (error) |
250 | goto out_stop; | 250 | goto out_stop; |
251 | update_mode = 1; | 251 | if (mode != inode->i_mode) |
252 | update_mode = 1; | ||
252 | } | 253 | } |
253 | 254 | ||
254 | error = __ext4_set_acl(handle, inode, type, acl, 0 /* xattr_flags */); | 255 | error = __ext4_set_acl(handle, inode, type, acl, 0 /* xattr_flags */); |
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 3f89d0ab08fc..185a05d3257e 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h | |||
@@ -2454,8 +2454,19 @@ int do_journal_get_write_access(handle_t *handle, | |||
2454 | #define FALL_BACK_TO_NONDELALLOC 1 | 2454 | #define FALL_BACK_TO_NONDELALLOC 1 |
2455 | #define CONVERT_INLINE_DATA 2 | 2455 | #define CONVERT_INLINE_DATA 2 |
2456 | 2456 | ||
2457 | extern struct inode *ext4_iget(struct super_block *, unsigned long); | 2457 | typedef enum { |
2458 | extern struct inode *ext4_iget_normal(struct super_block *, unsigned long); | 2458 | EXT4_IGET_NORMAL = 0, |
2459 | EXT4_IGET_SPECIAL = 0x0001, /* OK to iget a system inode */ | ||
2460 | EXT4_IGET_HANDLE = 0x0002 /* Inode # is from a handle */ | ||
2461 | } ext4_iget_flags; | ||
2462 | |||
2463 | extern struct inode *__ext4_iget(struct super_block *sb, unsigned long ino, | ||
2464 | ext4_iget_flags flags, const char *function, | ||
2465 | unsigned int line); | ||
2466 | |||
2467 | #define ext4_iget(sb, ino, flags) \ | ||
2468 | __ext4_iget((sb), (ino), (flags), __func__, __LINE__) | ||
2469 | |||
2459 | extern int ext4_write_inode(struct inode *, struct writeback_control *); | 2470 | extern int ext4_write_inode(struct inode *, struct writeback_control *); |
2460 | extern int ext4_setattr(struct dentry *, struct iattr *); | 2471 | extern int ext4_setattr(struct dentry *, struct iattr *); |
2461 | extern int ext4_getattr(const struct path *, struct kstat *, u32, unsigned int); | 2472 | extern int ext4_getattr(const struct path *, struct kstat *, u32, unsigned int); |
@@ -2538,6 +2549,8 @@ extern int ext4_group_extend(struct super_block *sb, | |||
2538 | extern int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count); | 2549 | extern int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count); |
2539 | 2550 | ||
2540 | /* super.c */ | 2551 | /* super.c */ |
2552 | extern struct buffer_head *ext4_sb_bread(struct super_block *sb, | ||
2553 | sector_t block, int op_flags); | ||
2541 | extern int ext4_seq_options_show(struct seq_file *seq, void *offset); | 2554 | extern int ext4_seq_options_show(struct seq_file *seq, void *offset); |
2542 | extern int ext4_calculate_overhead(struct super_block *sb); | 2555 | extern int ext4_calculate_overhead(struct super_block *sb); |
2543 | extern void ext4_superblock_csum_set(struct super_block *sb); | 2556 | extern void ext4_superblock_csum_set(struct super_block *sb); |
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index 014f6a698cb7..7ff14a1adba3 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c | |||
@@ -1225,7 +1225,7 @@ struct inode *ext4_orphan_get(struct super_block *sb, unsigned long ino) | |||
1225 | if (!ext4_test_bit(bit, bitmap_bh->b_data)) | 1225 | if (!ext4_test_bit(bit, bitmap_bh->b_data)) |
1226 | goto bad_orphan; | 1226 | goto bad_orphan; |
1227 | 1227 | ||
1228 | inode = ext4_iget(sb, ino); | 1228 | inode = ext4_iget(sb, ino, EXT4_IGET_NORMAL); |
1229 | if (IS_ERR(inode)) { | 1229 | if (IS_ERR(inode)) { |
1230 | err = PTR_ERR(inode); | 1230 | err = PTR_ERR(inode); |
1231 | ext4_error(sb, "couldn't read orphan inode %lu (err %d)", | 1231 | ext4_error(sb, "couldn't read orphan inode %lu (err %d)", |
diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c index 9c4bac18cc6c..27373d88b5f0 100644 --- a/fs/ext4/inline.c +++ b/fs/ext4/inline.c | |||
@@ -705,8 +705,11 @@ int ext4_try_to_write_inline_data(struct address_space *mapping, | |||
705 | 705 | ||
706 | if (!PageUptodate(page)) { | 706 | if (!PageUptodate(page)) { |
707 | ret = ext4_read_inline_page(inode, page); | 707 | ret = ext4_read_inline_page(inode, page); |
708 | if (ret < 0) | 708 | if (ret < 0) { |
709 | unlock_page(page); | ||
710 | put_page(page); | ||
709 | goto out_up_read; | 711 | goto out_up_read; |
712 | } | ||
710 | } | 713 | } |
711 | 714 | ||
712 | ret = 1; | 715 | ret = 1; |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 22a9d8159720..9affabd07682 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -4817,7 +4817,9 @@ static inline u64 ext4_inode_peek_iversion(const struct inode *inode) | |||
4817 | return inode_peek_iversion(inode); | 4817 | return inode_peek_iversion(inode); |
4818 | } | 4818 | } |
4819 | 4819 | ||
4820 | struct inode *ext4_iget(struct super_block *sb, unsigned long ino) | 4820 | struct inode *__ext4_iget(struct super_block *sb, unsigned long ino, |
4821 | ext4_iget_flags flags, const char *function, | ||
4822 | unsigned int line) | ||
4821 | { | 4823 | { |
4822 | struct ext4_iloc iloc; | 4824 | struct ext4_iloc iloc; |
4823 | struct ext4_inode *raw_inode; | 4825 | struct ext4_inode *raw_inode; |
@@ -4831,6 +4833,18 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino) | |||
4831 | gid_t i_gid; | 4833 | gid_t i_gid; |
4832 | projid_t i_projid; | 4834 | projid_t i_projid; |
4833 | 4835 | ||
4836 | if (((flags & EXT4_IGET_NORMAL) && | ||
4837 | (ino < EXT4_FIRST_INO(sb) && ino != EXT4_ROOT_INO)) || | ||
4838 | (ino < EXT4_ROOT_INO) || | ||
4839 | (ino > le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count))) { | ||
4840 | if (flags & EXT4_IGET_HANDLE) | ||
4841 | return ERR_PTR(-ESTALE); | ||
4842 | __ext4_error(sb, function, line, | ||
4843 | "inode #%lu: comm %s: iget: illegal inode #", | ||
4844 | ino, current->comm); | ||
4845 | return ERR_PTR(-EFSCORRUPTED); | ||
4846 | } | ||
4847 | |||
4834 | inode = iget_locked(sb, ino); | 4848 | inode = iget_locked(sb, ino); |
4835 | if (!inode) | 4849 | if (!inode) |
4836 | return ERR_PTR(-ENOMEM); | 4850 | return ERR_PTR(-ENOMEM); |
@@ -4846,18 +4860,26 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino) | |||
4846 | raw_inode = ext4_raw_inode(&iloc); | 4860 | raw_inode = ext4_raw_inode(&iloc); |
4847 | 4861 | ||
4848 | if ((ino == EXT4_ROOT_INO) && (raw_inode->i_links_count == 0)) { | 4862 | if ((ino == EXT4_ROOT_INO) && (raw_inode->i_links_count == 0)) { |
4849 | EXT4_ERROR_INODE(inode, "root inode unallocated"); | 4863 | ext4_error_inode(inode, function, line, 0, |
4864 | "iget: root inode unallocated"); | ||
4850 | ret = -EFSCORRUPTED; | 4865 | ret = -EFSCORRUPTED; |
4851 | goto bad_inode; | 4866 | goto bad_inode; |
4852 | } | 4867 | } |
4853 | 4868 | ||
4869 | if ((flags & EXT4_IGET_HANDLE) && | ||
4870 | (raw_inode->i_links_count == 0) && (raw_inode->i_mode == 0)) { | ||
4871 | ret = -ESTALE; | ||
4872 | goto bad_inode; | ||
4873 | } | ||
4874 | |||
4854 | if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE) { | 4875 | if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE) { |
4855 | ei->i_extra_isize = le16_to_cpu(raw_inode->i_extra_isize); | 4876 | ei->i_extra_isize = le16_to_cpu(raw_inode->i_extra_isize); |
4856 | if (EXT4_GOOD_OLD_INODE_SIZE + ei->i_extra_isize > | 4877 | if (EXT4_GOOD_OLD_INODE_SIZE + ei->i_extra_isize > |
4857 | EXT4_INODE_SIZE(inode->i_sb) || | 4878 | EXT4_INODE_SIZE(inode->i_sb) || |
4858 | (ei->i_extra_isize & 3)) { | 4879 | (ei->i_extra_isize & 3)) { |
4859 | EXT4_ERROR_INODE(inode, | 4880 | ext4_error_inode(inode, function, line, 0, |
4860 | "bad extra_isize %u (inode size %u)", | 4881 | "iget: bad extra_isize %u " |
4882 | "(inode size %u)", | ||
4861 | ei->i_extra_isize, | 4883 | ei->i_extra_isize, |
4862 | EXT4_INODE_SIZE(inode->i_sb)); | 4884 | EXT4_INODE_SIZE(inode->i_sb)); |
4863 | ret = -EFSCORRUPTED; | 4885 | ret = -EFSCORRUPTED; |
@@ -4879,7 +4901,8 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino) | |||
4879 | } | 4901 | } |
4880 | 4902 | ||
4881 | if (!ext4_inode_csum_verify(inode, raw_inode, ei)) { | 4903 | if (!ext4_inode_csum_verify(inode, raw_inode, ei)) { |
4882 | EXT4_ERROR_INODE(inode, "checksum invalid"); | 4904 | ext4_error_inode(inode, function, line, 0, |
4905 | "iget: checksum invalid"); | ||
4883 | ret = -EFSBADCRC; | 4906 | ret = -EFSBADCRC; |
4884 | goto bad_inode; | 4907 | goto bad_inode; |
4885 | } | 4908 | } |
@@ -4936,7 +4959,8 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino) | |||
4936 | ((__u64)le16_to_cpu(raw_inode->i_file_acl_high)) << 32; | 4959 | ((__u64)le16_to_cpu(raw_inode->i_file_acl_high)) << 32; |
4937 | inode->i_size = ext4_isize(sb, raw_inode); | 4960 | inode->i_size = ext4_isize(sb, raw_inode); |
4938 | if ((size = i_size_read(inode)) < 0) { | 4961 | if ((size = i_size_read(inode)) < 0) { |
4939 | EXT4_ERROR_INODE(inode, "bad i_size value: %lld", size); | 4962 | ext4_error_inode(inode, function, line, 0, |
4963 | "iget: bad i_size value: %lld", size); | ||
4940 | ret = -EFSCORRUPTED; | 4964 | ret = -EFSCORRUPTED; |
4941 | goto bad_inode; | 4965 | goto bad_inode; |
4942 | } | 4966 | } |
@@ -5012,7 +5036,8 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino) | |||
5012 | ret = 0; | 5036 | ret = 0; |
5013 | if (ei->i_file_acl && | 5037 | if (ei->i_file_acl && |
5014 | !ext4_data_block_valid(EXT4_SB(sb), ei->i_file_acl, 1)) { | 5038 | !ext4_data_block_valid(EXT4_SB(sb), ei->i_file_acl, 1)) { |
5015 | EXT4_ERROR_INODE(inode, "bad extended attribute block %llu", | 5039 | ext4_error_inode(inode, function, line, 0, |
5040 | "iget: bad extended attribute block %llu", | ||
5016 | ei->i_file_acl); | 5041 | ei->i_file_acl); |
5017 | ret = -EFSCORRUPTED; | 5042 | ret = -EFSCORRUPTED; |
5018 | goto bad_inode; | 5043 | goto bad_inode; |
@@ -5040,8 +5065,9 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino) | |||
5040 | } else if (S_ISLNK(inode->i_mode)) { | 5065 | } else if (S_ISLNK(inode->i_mode)) { |
5041 | /* VFS does not allow setting these so must be corruption */ | 5066 | /* VFS does not allow setting these so must be corruption */ |
5042 | if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) { | 5067 | if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) { |
5043 | EXT4_ERROR_INODE(inode, | 5068 | ext4_error_inode(inode, function, line, 0, |
5044 | "immutable or append flags not allowed on symlinks"); | 5069 | "iget: immutable or append flags " |
5070 | "not allowed on symlinks"); | ||
5045 | ret = -EFSCORRUPTED; | 5071 | ret = -EFSCORRUPTED; |
5046 | goto bad_inode; | 5072 | goto bad_inode; |
5047 | } | 5073 | } |
@@ -5071,7 +5097,8 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino) | |||
5071 | make_bad_inode(inode); | 5097 | make_bad_inode(inode); |
5072 | } else { | 5098 | } else { |
5073 | ret = -EFSCORRUPTED; | 5099 | ret = -EFSCORRUPTED; |
5074 | EXT4_ERROR_INODE(inode, "bogus i_mode (%o)", inode->i_mode); | 5100 | ext4_error_inode(inode, function, line, 0, |
5101 | "iget: bogus i_mode (%o)", inode->i_mode); | ||
5075 | goto bad_inode; | 5102 | goto bad_inode; |
5076 | } | 5103 | } |
5077 | brelse(iloc.bh); | 5104 | brelse(iloc.bh); |
@@ -5085,13 +5112,6 @@ bad_inode: | |||
5085 | return ERR_PTR(ret); | 5112 | return ERR_PTR(ret); |
5086 | } | 5113 | } |
5087 | 5114 | ||
5088 | struct inode *ext4_iget_normal(struct super_block *sb, unsigned long ino) | ||
5089 | { | ||
5090 | if (ino < EXT4_FIRST_INO(sb) && ino != EXT4_ROOT_INO) | ||
5091 | return ERR_PTR(-EFSCORRUPTED); | ||
5092 | return ext4_iget(sb, ino); | ||
5093 | } | ||
5094 | |||
5095 | static int ext4_inode_blocks_set(handle_t *handle, | 5115 | static int ext4_inode_blocks_set(handle_t *handle, |
5096 | struct ext4_inode *raw_inode, | 5116 | struct ext4_inode *raw_inode, |
5097 | struct ext4_inode_info *ei) | 5117 | struct ext4_inode_info *ei) |
@@ -5380,9 +5400,13 @@ int ext4_write_inode(struct inode *inode, struct writeback_control *wbc) | |||
5380 | { | 5400 | { |
5381 | int err; | 5401 | int err; |
5382 | 5402 | ||
5383 | if (WARN_ON_ONCE(current->flags & PF_MEMALLOC)) | 5403 | if (WARN_ON_ONCE(current->flags & PF_MEMALLOC) || |
5404 | sb_rdonly(inode->i_sb)) | ||
5384 | return 0; | 5405 | return 0; |
5385 | 5406 | ||
5407 | if (unlikely(ext4_forced_shutdown(EXT4_SB(inode->i_sb)))) | ||
5408 | return -EIO; | ||
5409 | |||
5386 | if (EXT4_SB(inode->i_sb)->s_journal) { | 5410 | if (EXT4_SB(inode->i_sb)->s_journal) { |
5387 | if (ext4_journal_current_handle()) { | 5411 | if (ext4_journal_current_handle()) { |
5388 | jbd_debug(1, "called recursively, non-PF_MEMALLOC!\n"); | 5412 | jbd_debug(1, "called recursively, non-PF_MEMALLOC!\n"); |
@@ -5398,7 +5422,8 @@ int ext4_write_inode(struct inode *inode, struct writeback_control *wbc) | |||
5398 | if (wbc->sync_mode != WB_SYNC_ALL || wbc->for_sync) | 5422 | if (wbc->sync_mode != WB_SYNC_ALL || wbc->for_sync) |
5399 | return 0; | 5423 | return 0; |
5400 | 5424 | ||
5401 | err = ext4_force_commit(inode->i_sb); | 5425 | err = jbd2_complete_transaction(EXT4_SB(inode->i_sb)->s_journal, |
5426 | EXT4_I(inode)->i_sync_tid); | ||
5402 | } else { | 5427 | } else { |
5403 | struct ext4_iloc iloc; | 5428 | struct ext4_iloc iloc; |
5404 | 5429 | ||
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c index 0edee31913d1..d37dafa1d133 100644 --- a/fs/ext4/ioctl.c +++ b/fs/ext4/ioctl.c | |||
@@ -125,7 +125,7 @@ static long swap_inode_boot_loader(struct super_block *sb, | |||
125 | !inode_owner_or_capable(inode) || !capable(CAP_SYS_ADMIN)) | 125 | !inode_owner_or_capable(inode) || !capable(CAP_SYS_ADMIN)) |
126 | return -EPERM; | 126 | return -EPERM; |
127 | 127 | ||
128 | inode_bl = ext4_iget(sb, EXT4_BOOT_LOADER_INO); | 128 | inode_bl = ext4_iget(sb, EXT4_BOOT_LOADER_INO, EXT4_IGET_SPECIAL); |
129 | if (IS_ERR(inode_bl)) | 129 | if (IS_ERR(inode_bl)) |
130 | return PTR_ERR(inode_bl); | 130 | return PTR_ERR(inode_bl); |
131 | ei_bl = EXT4_I(inode_bl); | 131 | ei_bl = EXT4_I(inode_bl); |
diff --git a/fs/ext4/migrate.c b/fs/ext4/migrate.c index 61a9d1927817..b1e4d359f73b 100644 --- a/fs/ext4/migrate.c +++ b/fs/ext4/migrate.c | |||
@@ -116,9 +116,9 @@ static int update_ind_extent_range(handle_t *handle, struct inode *inode, | |||
116 | int i, retval = 0; | 116 | int i, retval = 0; |
117 | unsigned long max_entries = inode->i_sb->s_blocksize >> 2; | 117 | unsigned long max_entries = inode->i_sb->s_blocksize >> 2; |
118 | 118 | ||
119 | bh = sb_bread(inode->i_sb, pblock); | 119 | bh = ext4_sb_bread(inode->i_sb, pblock, 0); |
120 | if (!bh) | 120 | if (IS_ERR(bh)) |
121 | return -EIO; | 121 | return PTR_ERR(bh); |
122 | 122 | ||
123 | i_data = (__le32 *)bh->b_data; | 123 | i_data = (__le32 *)bh->b_data; |
124 | for (i = 0; i < max_entries; i++) { | 124 | for (i = 0; i < max_entries; i++) { |
@@ -145,9 +145,9 @@ static int update_dind_extent_range(handle_t *handle, struct inode *inode, | |||
145 | int i, retval = 0; | 145 | int i, retval = 0; |
146 | unsigned long max_entries = inode->i_sb->s_blocksize >> 2; | 146 | unsigned long max_entries = inode->i_sb->s_blocksize >> 2; |
147 | 147 | ||
148 | bh = sb_bread(inode->i_sb, pblock); | 148 | bh = ext4_sb_bread(inode->i_sb, pblock, 0); |
149 | if (!bh) | 149 | if (IS_ERR(bh)) |
150 | return -EIO; | 150 | return PTR_ERR(bh); |
151 | 151 | ||
152 | i_data = (__le32 *)bh->b_data; | 152 | i_data = (__le32 *)bh->b_data; |
153 | for (i = 0; i < max_entries; i++) { | 153 | for (i = 0; i < max_entries; i++) { |
@@ -175,9 +175,9 @@ static int update_tind_extent_range(handle_t *handle, struct inode *inode, | |||
175 | int i, retval = 0; | 175 | int i, retval = 0; |
176 | unsigned long max_entries = inode->i_sb->s_blocksize >> 2; | 176 | unsigned long max_entries = inode->i_sb->s_blocksize >> 2; |
177 | 177 | ||
178 | bh = sb_bread(inode->i_sb, pblock); | 178 | bh = ext4_sb_bread(inode->i_sb, pblock, 0); |
179 | if (!bh) | 179 | if (IS_ERR(bh)) |
180 | return -EIO; | 180 | return PTR_ERR(bh); |
181 | 181 | ||
182 | i_data = (__le32 *)bh->b_data; | 182 | i_data = (__le32 *)bh->b_data; |
183 | for (i = 0; i < max_entries; i++) { | 183 | for (i = 0; i < max_entries; i++) { |
@@ -224,9 +224,9 @@ static int free_dind_blocks(handle_t *handle, | |||
224 | struct buffer_head *bh; | 224 | struct buffer_head *bh; |
225 | unsigned long max_entries = inode->i_sb->s_blocksize >> 2; | 225 | unsigned long max_entries = inode->i_sb->s_blocksize >> 2; |
226 | 226 | ||
227 | bh = sb_bread(inode->i_sb, le32_to_cpu(i_data)); | 227 | bh = ext4_sb_bread(inode->i_sb, le32_to_cpu(i_data), 0); |
228 | if (!bh) | 228 | if (IS_ERR(bh)) |
229 | return -EIO; | 229 | return PTR_ERR(bh); |
230 | 230 | ||
231 | tmp_idata = (__le32 *)bh->b_data; | 231 | tmp_idata = (__le32 *)bh->b_data; |
232 | for (i = 0; i < max_entries; i++) { | 232 | for (i = 0; i < max_entries; i++) { |
@@ -254,9 +254,9 @@ static int free_tind_blocks(handle_t *handle, | |||
254 | struct buffer_head *bh; | 254 | struct buffer_head *bh; |
255 | unsigned long max_entries = inode->i_sb->s_blocksize >> 2; | 255 | unsigned long max_entries = inode->i_sb->s_blocksize >> 2; |
256 | 256 | ||
257 | bh = sb_bread(inode->i_sb, le32_to_cpu(i_data)); | 257 | bh = ext4_sb_bread(inode->i_sb, le32_to_cpu(i_data), 0); |
258 | if (!bh) | 258 | if (IS_ERR(bh)) |
259 | return -EIO; | 259 | return PTR_ERR(bh); |
260 | 260 | ||
261 | tmp_idata = (__le32 *)bh->b_data; | 261 | tmp_idata = (__le32 *)bh->b_data; |
262 | for (i = 0; i < max_entries; i++) { | 262 | for (i = 0; i < max_entries; i++) { |
@@ -382,9 +382,9 @@ static int free_ext_idx(handle_t *handle, struct inode *inode, | |||
382 | struct ext4_extent_header *eh; | 382 | struct ext4_extent_header *eh; |
383 | 383 | ||
384 | block = ext4_idx_pblock(ix); | 384 | block = ext4_idx_pblock(ix); |
385 | bh = sb_bread(inode->i_sb, block); | 385 | bh = ext4_sb_bread(inode->i_sb, block, 0); |
386 | if (!bh) | 386 | if (IS_ERR(bh)) |
387 | return -EIO; | 387 | return PTR_ERR(bh); |
388 | 388 | ||
389 | eh = (struct ext4_extent_header *)bh->b_data; | 389 | eh = (struct ext4_extent_header *)bh->b_data; |
390 | if (eh->eh_depth != 0) { | 390 | if (eh->eh_depth != 0) { |
@@ -535,22 +535,22 @@ int ext4_ext_migrate(struct inode *inode) | |||
535 | if (i_data[EXT4_IND_BLOCK]) { | 535 | if (i_data[EXT4_IND_BLOCK]) { |
536 | retval = update_ind_extent_range(handle, tmp_inode, | 536 | retval = update_ind_extent_range(handle, tmp_inode, |
537 | le32_to_cpu(i_data[EXT4_IND_BLOCK]), &lb); | 537 | le32_to_cpu(i_data[EXT4_IND_BLOCK]), &lb); |
538 | if (retval) | 538 | if (retval) |
539 | goto err_out; | 539 | goto err_out; |
540 | } else | 540 | } else |
541 | lb.curr_block += max_entries; | 541 | lb.curr_block += max_entries; |
542 | if (i_data[EXT4_DIND_BLOCK]) { | 542 | if (i_data[EXT4_DIND_BLOCK]) { |
543 | retval = update_dind_extent_range(handle, tmp_inode, | 543 | retval = update_dind_extent_range(handle, tmp_inode, |
544 | le32_to_cpu(i_data[EXT4_DIND_BLOCK]), &lb); | 544 | le32_to_cpu(i_data[EXT4_DIND_BLOCK]), &lb); |
545 | if (retval) | 545 | if (retval) |
546 | goto err_out; | 546 | goto err_out; |
547 | } else | 547 | } else |
548 | lb.curr_block += max_entries * max_entries; | 548 | lb.curr_block += max_entries * max_entries; |
549 | if (i_data[EXT4_TIND_BLOCK]) { | 549 | if (i_data[EXT4_TIND_BLOCK]) { |
550 | retval = update_tind_extent_range(handle, tmp_inode, | 550 | retval = update_tind_extent_range(handle, tmp_inode, |
551 | le32_to_cpu(i_data[EXT4_TIND_BLOCK]), &lb); | 551 | le32_to_cpu(i_data[EXT4_TIND_BLOCK]), &lb); |
552 | if (retval) | 552 | if (retval) |
553 | goto err_out; | 553 | goto err_out; |
554 | } | 554 | } |
555 | /* | 555 | /* |
556 | * Build the last extent | 556 | * Build the last extent |
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 437f71fe83ae..2b928eb07fa2 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c | |||
@@ -1571,7 +1571,7 @@ static struct dentry *ext4_lookup(struct inode *dir, struct dentry *dentry, unsi | |||
1571 | dentry); | 1571 | dentry); |
1572 | return ERR_PTR(-EFSCORRUPTED); | 1572 | return ERR_PTR(-EFSCORRUPTED); |
1573 | } | 1573 | } |
1574 | inode = ext4_iget_normal(dir->i_sb, ino); | 1574 | inode = ext4_iget(dir->i_sb, ino, EXT4_IGET_NORMAL); |
1575 | if (inode == ERR_PTR(-ESTALE)) { | 1575 | if (inode == ERR_PTR(-ESTALE)) { |
1576 | EXT4_ERROR_INODE(dir, | 1576 | EXT4_ERROR_INODE(dir, |
1577 | "deleted inode referenced: %u", | 1577 | "deleted inode referenced: %u", |
@@ -1613,7 +1613,7 @@ struct dentry *ext4_get_parent(struct dentry *child) | |||
1613 | return ERR_PTR(-EFSCORRUPTED); | 1613 | return ERR_PTR(-EFSCORRUPTED); |
1614 | } | 1614 | } |
1615 | 1615 | ||
1616 | return d_obtain_alias(ext4_iget_normal(child->d_sb, ino)); | 1616 | return d_obtain_alias(ext4_iget(child->d_sb, ino, EXT4_IGET_NORMAL)); |
1617 | } | 1617 | } |
1618 | 1618 | ||
1619 | /* | 1619 | /* |
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c index a5efee34415f..48421de803b7 100644 --- a/fs/ext4/resize.c +++ b/fs/ext4/resize.c | |||
@@ -127,10 +127,12 @@ static int verify_group_input(struct super_block *sb, | |||
127 | else if (free_blocks_count < 0) | 127 | else if (free_blocks_count < 0) |
128 | ext4_warning(sb, "Bad blocks count %u", | 128 | ext4_warning(sb, "Bad blocks count %u", |
129 | input->blocks_count); | 129 | input->blocks_count); |
130 | else if (!(bh = sb_bread(sb, end - 1))) | 130 | else if (IS_ERR(bh = ext4_sb_bread(sb, end - 1, 0))) { |
131 | err = PTR_ERR(bh); | ||
132 | bh = NULL; | ||
131 | ext4_warning(sb, "Cannot read last block (%llu)", | 133 | ext4_warning(sb, "Cannot read last block (%llu)", |
132 | end - 1); | 134 | end - 1); |
133 | else if (outside(input->block_bitmap, start, end)) | 135 | } else if (outside(input->block_bitmap, start, end)) |
134 | ext4_warning(sb, "Block bitmap not in group (block %llu)", | 136 | ext4_warning(sb, "Block bitmap not in group (block %llu)", |
135 | (unsigned long long)input->block_bitmap); | 137 | (unsigned long long)input->block_bitmap); |
136 | else if (outside(input->inode_bitmap, start, end)) | 138 | else if (outside(input->inode_bitmap, start, end)) |
@@ -781,11 +783,11 @@ static int add_new_gdb(handle_t *handle, struct inode *inode, | |||
781 | struct ext4_super_block *es = EXT4_SB(sb)->s_es; | 783 | struct ext4_super_block *es = EXT4_SB(sb)->s_es; |
782 | unsigned long gdb_num = group / EXT4_DESC_PER_BLOCK(sb); | 784 | unsigned long gdb_num = group / EXT4_DESC_PER_BLOCK(sb); |
783 | ext4_fsblk_t gdblock = EXT4_SB(sb)->s_sbh->b_blocknr + 1 + gdb_num; | 785 | ext4_fsblk_t gdblock = EXT4_SB(sb)->s_sbh->b_blocknr + 1 + gdb_num; |
784 | struct buffer_head **o_group_desc, **n_group_desc; | 786 | struct buffer_head **o_group_desc, **n_group_desc = NULL; |
785 | struct buffer_head *dind; | 787 | struct buffer_head *dind = NULL; |
786 | struct buffer_head *gdb_bh; | 788 | struct buffer_head *gdb_bh = NULL; |
787 | int gdbackups; | 789 | int gdbackups; |
788 | struct ext4_iloc iloc; | 790 | struct ext4_iloc iloc = { .bh = NULL }; |
789 | __le32 *data; | 791 | __le32 *data; |
790 | int err; | 792 | int err; |
791 | 793 | ||
@@ -794,21 +796,22 @@ static int add_new_gdb(handle_t *handle, struct inode *inode, | |||
794 | "EXT4-fs: ext4_add_new_gdb: adding group block %lu\n", | 796 | "EXT4-fs: ext4_add_new_gdb: adding group block %lu\n", |
795 | gdb_num); | 797 | gdb_num); |
796 | 798 | ||
797 | gdb_bh = sb_bread(sb, gdblock); | 799 | gdb_bh = ext4_sb_bread(sb, gdblock, 0); |
798 | if (!gdb_bh) | 800 | if (IS_ERR(gdb_bh)) |
799 | return -EIO; | 801 | return PTR_ERR(gdb_bh); |
800 | 802 | ||
801 | gdbackups = verify_reserved_gdb(sb, group, gdb_bh); | 803 | gdbackups = verify_reserved_gdb(sb, group, gdb_bh); |
802 | if (gdbackups < 0) { | 804 | if (gdbackups < 0) { |
803 | err = gdbackups; | 805 | err = gdbackups; |
804 | goto exit_bh; | 806 | goto errout; |
805 | } | 807 | } |
806 | 808 | ||
807 | data = EXT4_I(inode)->i_data + EXT4_DIND_BLOCK; | 809 | data = EXT4_I(inode)->i_data + EXT4_DIND_BLOCK; |
808 | dind = sb_bread(sb, le32_to_cpu(*data)); | 810 | dind = ext4_sb_bread(sb, le32_to_cpu(*data), 0); |
809 | if (!dind) { | 811 | if (IS_ERR(dind)) { |
810 | err = -EIO; | 812 | err = PTR_ERR(dind); |
811 | goto exit_bh; | 813 | dind = NULL; |
814 | goto errout; | ||
812 | } | 815 | } |
813 | 816 | ||
814 | data = (__le32 *)dind->b_data; | 817 | data = (__le32 *)dind->b_data; |
@@ -816,18 +819,18 @@ static int add_new_gdb(handle_t *handle, struct inode *inode, | |||
816 | ext4_warning(sb, "new group %u GDT block %llu not reserved", | 819 | ext4_warning(sb, "new group %u GDT block %llu not reserved", |
817 | group, gdblock); | 820 | group, gdblock); |
818 | err = -EINVAL; | 821 | err = -EINVAL; |
819 | goto exit_dind; | 822 | goto errout; |
820 | } | 823 | } |
821 | 824 | ||
822 | BUFFER_TRACE(EXT4_SB(sb)->s_sbh, "get_write_access"); | 825 | BUFFER_TRACE(EXT4_SB(sb)->s_sbh, "get_write_access"); |
823 | err = ext4_journal_get_write_access(handle, EXT4_SB(sb)->s_sbh); | 826 | err = ext4_journal_get_write_access(handle, EXT4_SB(sb)->s_sbh); |
824 | if (unlikely(err)) | 827 | if (unlikely(err)) |
825 | goto exit_dind; | 828 | goto errout; |
826 | 829 | ||
827 | BUFFER_TRACE(gdb_bh, "get_write_access"); | 830 | BUFFER_TRACE(gdb_bh, "get_write_access"); |
828 | err = ext4_journal_get_write_access(handle, gdb_bh); | 831 | err = ext4_journal_get_write_access(handle, gdb_bh); |
829 | if (unlikely(err)) | 832 | if (unlikely(err)) |
830 | goto exit_dind; | 833 | goto errout; |
831 | 834 | ||
832 | BUFFER_TRACE(dind, "get_write_access"); | 835 | BUFFER_TRACE(dind, "get_write_access"); |
833 | err = ext4_journal_get_write_access(handle, dind); | 836 | err = ext4_journal_get_write_access(handle, dind); |
@@ -837,7 +840,7 @@ static int add_new_gdb(handle_t *handle, struct inode *inode, | |||
837 | /* ext4_reserve_inode_write() gets a reference on the iloc */ | 840 | /* ext4_reserve_inode_write() gets a reference on the iloc */ |
838 | err = ext4_reserve_inode_write(handle, inode, &iloc); | 841 | err = ext4_reserve_inode_write(handle, inode, &iloc); |
839 | if (unlikely(err)) | 842 | if (unlikely(err)) |
840 | goto exit_dind; | 843 | goto errout; |
841 | 844 | ||
842 | n_group_desc = ext4_kvmalloc((gdb_num + 1) * | 845 | n_group_desc = ext4_kvmalloc((gdb_num + 1) * |
843 | sizeof(struct buffer_head *), | 846 | sizeof(struct buffer_head *), |
@@ -846,7 +849,7 @@ static int add_new_gdb(handle_t *handle, struct inode *inode, | |||
846 | err = -ENOMEM; | 849 | err = -ENOMEM; |
847 | ext4_warning(sb, "not enough memory for %lu groups", | 850 | ext4_warning(sb, "not enough memory for %lu groups", |
848 | gdb_num + 1); | 851 | gdb_num + 1); |
849 | goto exit_inode; | 852 | goto errout; |
850 | } | 853 | } |
851 | 854 | ||
852 | /* | 855 | /* |
@@ -862,7 +865,7 @@ static int add_new_gdb(handle_t *handle, struct inode *inode, | |||
862 | err = ext4_handle_dirty_metadata(handle, NULL, dind); | 865 | err = ext4_handle_dirty_metadata(handle, NULL, dind); |
863 | if (unlikely(err)) { | 866 | if (unlikely(err)) { |
864 | ext4_std_error(sb, err); | 867 | ext4_std_error(sb, err); |
865 | goto exit_inode; | 868 | goto errout; |
866 | } | 869 | } |
867 | inode->i_blocks -= (gdbackups + 1) * sb->s_blocksize >> | 870 | inode->i_blocks -= (gdbackups + 1) * sb->s_blocksize >> |
868 | (9 - EXT4_SB(sb)->s_cluster_bits); | 871 | (9 - EXT4_SB(sb)->s_cluster_bits); |
@@ -871,8 +874,7 @@ static int add_new_gdb(handle_t *handle, struct inode *inode, | |||
871 | err = ext4_handle_dirty_metadata(handle, NULL, gdb_bh); | 874 | err = ext4_handle_dirty_metadata(handle, NULL, gdb_bh); |
872 | if (unlikely(err)) { | 875 | if (unlikely(err)) { |
873 | ext4_std_error(sb, err); | 876 | ext4_std_error(sb, err); |
874 | iloc.bh = NULL; | 877 | goto errout; |
875 | goto exit_inode; | ||
876 | } | 878 | } |
877 | brelse(dind); | 879 | brelse(dind); |
878 | 880 | ||
@@ -888,15 +890,11 @@ static int add_new_gdb(handle_t *handle, struct inode *inode, | |||
888 | err = ext4_handle_dirty_super(handle, sb); | 890 | err = ext4_handle_dirty_super(handle, sb); |
889 | if (err) | 891 | if (err) |
890 | ext4_std_error(sb, err); | 892 | ext4_std_error(sb, err); |
891 | |||
892 | return err; | 893 | return err; |
893 | 894 | errout: | |
894 | exit_inode: | ||
895 | kvfree(n_group_desc); | 895 | kvfree(n_group_desc); |
896 | brelse(iloc.bh); | 896 | brelse(iloc.bh); |
897 | exit_dind: | ||
898 | brelse(dind); | 897 | brelse(dind); |
899 | exit_bh: | ||
900 | brelse(gdb_bh); | 898 | brelse(gdb_bh); |
901 | 899 | ||
902 | ext4_debug("leaving with error %d\n", err); | 900 | ext4_debug("leaving with error %d\n", err); |
@@ -916,9 +914,9 @@ static int add_new_gdb_meta_bg(struct super_block *sb, | |||
916 | 914 | ||
917 | gdblock = ext4_meta_bg_first_block_no(sb, group) + | 915 | gdblock = ext4_meta_bg_first_block_no(sb, group) + |
918 | ext4_bg_has_super(sb, group); | 916 | ext4_bg_has_super(sb, group); |
919 | gdb_bh = sb_bread(sb, gdblock); | 917 | gdb_bh = ext4_sb_bread(sb, gdblock, 0); |
920 | if (!gdb_bh) | 918 | if (IS_ERR(gdb_bh)) |
921 | return -EIO; | 919 | return PTR_ERR(gdb_bh); |
922 | n_group_desc = ext4_kvmalloc((gdb_num + 1) * | 920 | n_group_desc = ext4_kvmalloc((gdb_num + 1) * |
923 | sizeof(struct buffer_head *), | 921 | sizeof(struct buffer_head *), |
924 | GFP_NOFS); | 922 | GFP_NOFS); |
@@ -975,9 +973,10 @@ static int reserve_backup_gdb(handle_t *handle, struct inode *inode, | |||
975 | return -ENOMEM; | 973 | return -ENOMEM; |
976 | 974 | ||
977 | data = EXT4_I(inode)->i_data + EXT4_DIND_BLOCK; | 975 | data = EXT4_I(inode)->i_data + EXT4_DIND_BLOCK; |
978 | dind = sb_bread(sb, le32_to_cpu(*data)); | 976 | dind = ext4_sb_bread(sb, le32_to_cpu(*data), 0); |
979 | if (!dind) { | 977 | if (IS_ERR(dind)) { |
980 | err = -EIO; | 978 | err = PTR_ERR(dind); |
979 | dind = NULL; | ||
981 | goto exit_free; | 980 | goto exit_free; |
982 | } | 981 | } |
983 | 982 | ||
@@ -996,9 +995,10 @@ static int reserve_backup_gdb(handle_t *handle, struct inode *inode, | |||
996 | err = -EINVAL; | 995 | err = -EINVAL; |
997 | goto exit_bh; | 996 | goto exit_bh; |
998 | } | 997 | } |
999 | primary[res] = sb_bread(sb, blk); | 998 | primary[res] = ext4_sb_bread(sb, blk, 0); |
1000 | if (!primary[res]) { | 999 | if (IS_ERR(primary[res])) { |
1001 | err = -EIO; | 1000 | err = PTR_ERR(primary[res]); |
1001 | primary[res] = NULL; | ||
1002 | goto exit_bh; | 1002 | goto exit_bh; |
1003 | } | 1003 | } |
1004 | gdbackups = verify_reserved_gdb(sb, group, primary[res]); | 1004 | gdbackups = verify_reserved_gdb(sb, group, primary[res]); |
@@ -1631,13 +1631,13 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input) | |||
1631 | } | 1631 | } |
1632 | 1632 | ||
1633 | if (reserved_gdb || gdb_off == 0) { | 1633 | if (reserved_gdb || gdb_off == 0) { |
1634 | if (ext4_has_feature_resize_inode(sb) || | 1634 | if (!ext4_has_feature_resize_inode(sb) || |
1635 | !le16_to_cpu(es->s_reserved_gdt_blocks)) { | 1635 | !le16_to_cpu(es->s_reserved_gdt_blocks)) { |
1636 | ext4_warning(sb, | 1636 | ext4_warning(sb, |
1637 | "No reserved GDT blocks, can't resize"); | 1637 | "No reserved GDT blocks, can't resize"); |
1638 | return -EPERM; | 1638 | return -EPERM; |
1639 | } | 1639 | } |
1640 | inode = ext4_iget(sb, EXT4_RESIZE_INO); | 1640 | inode = ext4_iget(sb, EXT4_RESIZE_INO, EXT4_IGET_SPECIAL); |
1641 | if (IS_ERR(inode)) { | 1641 | if (IS_ERR(inode)) { |
1642 | ext4_warning(sb, "Error opening resize inode"); | 1642 | ext4_warning(sb, "Error opening resize inode"); |
1643 | return PTR_ERR(inode); | 1643 | return PTR_ERR(inode); |
@@ -1965,7 +1965,8 @@ retry: | |||
1965 | } | 1965 | } |
1966 | 1966 | ||
1967 | if (!resize_inode) | 1967 | if (!resize_inode) |
1968 | resize_inode = ext4_iget(sb, EXT4_RESIZE_INO); | 1968 | resize_inode = ext4_iget(sb, EXT4_RESIZE_INO, |
1969 | EXT4_IGET_SPECIAL); | ||
1969 | if (IS_ERR(resize_inode)) { | 1970 | if (IS_ERR(resize_inode)) { |
1970 | ext4_warning(sb, "Error opening resize inode"); | 1971 | ext4_warning(sb, "Error opening resize inode"); |
1971 | return PTR_ERR(resize_inode); | 1972 | return PTR_ERR(resize_inode); |
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 53ff6c2a26ed..d6c142d73d99 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -140,6 +140,29 @@ MODULE_ALIAS_FS("ext3"); | |||
140 | MODULE_ALIAS("ext3"); | 140 | MODULE_ALIAS("ext3"); |
141 | #define IS_EXT3_SB(sb) ((sb)->s_bdev->bd_holder == &ext3_fs_type) | 141 | #define IS_EXT3_SB(sb) ((sb)->s_bdev->bd_holder == &ext3_fs_type) |
142 | 142 | ||
143 | /* | ||
144 | * This works like sb_bread() except it uses ERR_PTR for error | ||
145 | * returns. Currently with sb_bread it's impossible to distinguish | ||
146 | * between ENOMEM and EIO situations (since both result in a NULL | ||
147 | * return. | ||
148 | */ | ||
149 | struct buffer_head * | ||
150 | ext4_sb_bread(struct super_block *sb, sector_t block, int op_flags) | ||
151 | { | ||
152 | struct buffer_head *bh = sb_getblk(sb, block); | ||
153 | |||
154 | if (bh == NULL) | ||
155 | return ERR_PTR(-ENOMEM); | ||
156 | if (buffer_uptodate(bh)) | ||
157 | return bh; | ||
158 | ll_rw_block(REQ_OP_READ, REQ_META | op_flags, 1, &bh); | ||
159 | wait_on_buffer(bh); | ||
160 | if (buffer_uptodate(bh)) | ||
161 | return bh; | ||
162 | put_bh(bh); | ||
163 | return ERR_PTR(-EIO); | ||
164 | } | ||
165 | |||
143 | static int ext4_verify_csum_type(struct super_block *sb, | 166 | static int ext4_verify_csum_type(struct super_block *sb, |
144 | struct ext4_super_block *es) | 167 | struct ext4_super_block *es) |
145 | { | 168 | { |
@@ -1000,14 +1023,13 @@ static void ext4_put_super(struct super_block *sb) | |||
1000 | invalidate_bdev(sbi->journal_bdev); | 1023 | invalidate_bdev(sbi->journal_bdev); |
1001 | ext4_blkdev_remove(sbi); | 1024 | ext4_blkdev_remove(sbi); |
1002 | } | 1025 | } |
1003 | if (sbi->s_ea_inode_cache) { | 1026 | |
1004 | ext4_xattr_destroy_cache(sbi->s_ea_inode_cache); | 1027 | ext4_xattr_destroy_cache(sbi->s_ea_inode_cache); |
1005 | sbi->s_ea_inode_cache = NULL; | 1028 | sbi->s_ea_inode_cache = NULL; |
1006 | } | 1029 | |
1007 | if (sbi->s_ea_block_cache) { | 1030 | ext4_xattr_destroy_cache(sbi->s_ea_block_cache); |
1008 | ext4_xattr_destroy_cache(sbi->s_ea_block_cache); | 1031 | sbi->s_ea_block_cache = NULL; |
1009 | sbi->s_ea_block_cache = NULL; | 1032 | |
1010 | } | ||
1011 | if (sbi->s_mmp_tsk) | 1033 | if (sbi->s_mmp_tsk) |
1012 | kthread_stop(sbi->s_mmp_tsk); | 1034 | kthread_stop(sbi->s_mmp_tsk); |
1013 | brelse(sbi->s_sbh); | 1035 | brelse(sbi->s_sbh); |
@@ -1151,20 +1173,11 @@ static struct inode *ext4_nfs_get_inode(struct super_block *sb, | |||
1151 | { | 1173 | { |
1152 | struct inode *inode; | 1174 | struct inode *inode; |
1153 | 1175 | ||
1154 | if (ino < EXT4_FIRST_INO(sb) && ino != EXT4_ROOT_INO) | 1176 | /* |
1155 | return ERR_PTR(-ESTALE); | ||
1156 | if (ino > le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count)) | ||
1157 | return ERR_PTR(-ESTALE); | ||
1158 | |||
1159 | /* iget isn't really right if the inode is currently unallocated!! | ||
1160 | * | ||
1161 | * ext4_read_inode will return a bad_inode if the inode had been | ||
1162 | * deleted, so we should be safe. | ||
1163 | * | ||
1164 | * Currently we don't know the generation for parent directory, so | 1177 | * Currently we don't know the generation for parent directory, so |
1165 | * a generation of 0 means "accept any" | 1178 | * a generation of 0 means "accept any" |
1166 | */ | 1179 | */ |
1167 | inode = ext4_iget_normal(sb, ino); | 1180 | inode = ext4_iget(sb, ino, EXT4_IGET_HANDLE); |
1168 | if (IS_ERR(inode)) | 1181 | if (IS_ERR(inode)) |
1169 | return ERR_CAST(inode); | 1182 | return ERR_CAST(inode); |
1170 | if (generation && inode->i_generation != generation) { | 1183 | if (generation && inode->i_generation != generation) { |
@@ -1189,6 +1202,16 @@ static struct dentry *ext4_fh_to_parent(struct super_block *sb, struct fid *fid, | |||
1189 | ext4_nfs_get_inode); | 1202 | ext4_nfs_get_inode); |
1190 | } | 1203 | } |
1191 | 1204 | ||
1205 | static int ext4_nfs_commit_metadata(struct inode *inode) | ||
1206 | { | ||
1207 | struct writeback_control wbc = { | ||
1208 | .sync_mode = WB_SYNC_ALL | ||
1209 | }; | ||
1210 | |||
1211 | trace_ext4_nfs_commit_metadata(inode); | ||
1212 | return ext4_write_inode(inode, &wbc); | ||
1213 | } | ||
1214 | |||
1192 | /* | 1215 | /* |
1193 | * Try to release metadata pages (indirect blocks, directories) which are | 1216 | * Try to release metadata pages (indirect blocks, directories) which are |
1194 | * mapped via the block device. Since these pages could have journal heads | 1217 | * mapped via the block device. Since these pages could have journal heads |
@@ -1393,6 +1416,7 @@ static const struct export_operations ext4_export_ops = { | |||
1393 | .fh_to_dentry = ext4_fh_to_dentry, | 1416 | .fh_to_dentry = ext4_fh_to_dentry, |
1394 | .fh_to_parent = ext4_fh_to_parent, | 1417 | .fh_to_parent = ext4_fh_to_parent, |
1395 | .get_parent = ext4_get_parent, | 1418 | .get_parent = ext4_get_parent, |
1419 | .commit_metadata = ext4_nfs_commit_metadata, | ||
1396 | }; | 1420 | }; |
1397 | 1421 | ||
1398 | enum { | 1422 | enum { |
@@ -1939,7 +1963,7 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token, | |||
1939 | #ifdef CONFIG_FS_DAX | 1963 | #ifdef CONFIG_FS_DAX |
1940 | ext4_msg(sb, KERN_WARNING, | 1964 | ext4_msg(sb, KERN_WARNING, |
1941 | "DAX enabled. Warning: EXPERIMENTAL, use at your own risk"); | 1965 | "DAX enabled. Warning: EXPERIMENTAL, use at your own risk"); |
1942 | sbi->s_mount_opt |= m->mount_opt; | 1966 | sbi->s_mount_opt |= m->mount_opt; |
1943 | #else | 1967 | #else |
1944 | ext4_msg(sb, KERN_INFO, "dax option not supported"); | 1968 | ext4_msg(sb, KERN_INFO, "dax option not supported"); |
1945 | return -1; | 1969 | return -1; |
@@ -3842,12 +3866,12 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
3842 | if (ext4_has_feature_inline_data(sb)) { | 3866 | if (ext4_has_feature_inline_data(sb)) { |
3843 | ext4_msg(sb, KERN_ERR, "Cannot use DAX on a filesystem" | 3867 | ext4_msg(sb, KERN_ERR, "Cannot use DAX on a filesystem" |
3844 | " that may contain inline data"); | 3868 | " that may contain inline data"); |
3845 | sbi->s_mount_opt &= ~EXT4_MOUNT_DAX; | 3869 | goto failed_mount; |
3846 | } | 3870 | } |
3847 | if (!bdev_dax_supported(sb->s_bdev, blocksize)) { | 3871 | if (!bdev_dax_supported(sb->s_bdev, blocksize)) { |
3848 | ext4_msg(sb, KERN_ERR, | 3872 | ext4_msg(sb, KERN_ERR, |
3849 | "DAX unsupported by block device. Turning off DAX."); | 3873 | "DAX unsupported by block device."); |
3850 | sbi->s_mount_opt &= ~EXT4_MOUNT_DAX; | 3874 | goto failed_mount; |
3851 | } | 3875 | } |
3852 | } | 3876 | } |
3853 | 3877 | ||
@@ -4328,7 +4352,7 @@ no_journal: | |||
4328 | * so we can safely mount the rest of the filesystem now. | 4352 | * so we can safely mount the rest of the filesystem now. |
4329 | */ | 4353 | */ |
4330 | 4354 | ||
4331 | root = ext4_iget(sb, EXT4_ROOT_INO); | 4355 | root = ext4_iget(sb, EXT4_ROOT_INO, EXT4_IGET_SPECIAL); |
4332 | if (IS_ERR(root)) { | 4356 | if (IS_ERR(root)) { |
4333 | ext4_msg(sb, KERN_ERR, "get root inode failed"); | 4357 | ext4_msg(sb, KERN_ERR, "get root inode failed"); |
4334 | ret = PTR_ERR(root); | 4358 | ret = PTR_ERR(root); |
@@ -4522,14 +4546,12 @@ failed_mount4: | |||
4522 | if (EXT4_SB(sb)->rsv_conversion_wq) | 4546 | if (EXT4_SB(sb)->rsv_conversion_wq) |
4523 | destroy_workqueue(EXT4_SB(sb)->rsv_conversion_wq); | 4547 | destroy_workqueue(EXT4_SB(sb)->rsv_conversion_wq); |
4524 | failed_mount_wq: | 4548 | failed_mount_wq: |
4525 | if (sbi->s_ea_inode_cache) { | 4549 | ext4_xattr_destroy_cache(sbi->s_ea_inode_cache); |
4526 | ext4_xattr_destroy_cache(sbi->s_ea_inode_cache); | 4550 | sbi->s_ea_inode_cache = NULL; |
4527 | sbi->s_ea_inode_cache = NULL; | 4551 | |
4528 | } | 4552 | ext4_xattr_destroy_cache(sbi->s_ea_block_cache); |
4529 | if (sbi->s_ea_block_cache) { | 4553 | sbi->s_ea_block_cache = NULL; |
4530 | ext4_xattr_destroy_cache(sbi->s_ea_block_cache); | 4554 | |
4531 | sbi->s_ea_block_cache = NULL; | ||
4532 | } | ||
4533 | if (sbi->s_journal) { | 4555 | if (sbi->s_journal) { |
4534 | jbd2_journal_destroy(sbi->s_journal); | 4556 | jbd2_journal_destroy(sbi->s_journal); |
4535 | sbi->s_journal = NULL; | 4557 | sbi->s_journal = NULL; |
@@ -4598,7 +4620,7 @@ static struct inode *ext4_get_journal_inode(struct super_block *sb, | |||
4598 | * happen if we iget() an unused inode, as the subsequent iput() | 4620 | * happen if we iget() an unused inode, as the subsequent iput() |
4599 | * will try to delete it. | 4621 | * will try to delete it. |
4600 | */ | 4622 | */ |
4601 | journal_inode = ext4_iget(sb, journal_inum); | 4623 | journal_inode = ext4_iget(sb, journal_inum, EXT4_IGET_SPECIAL); |
4602 | if (IS_ERR(journal_inode)) { | 4624 | if (IS_ERR(journal_inode)) { |
4603 | ext4_msg(sb, KERN_ERR, "no journal found"); | 4625 | ext4_msg(sb, KERN_ERR, "no journal found"); |
4604 | return NULL; | 4626 | return NULL; |
@@ -5680,7 +5702,7 @@ static int ext4_quota_enable(struct super_block *sb, int type, int format_id, | |||
5680 | if (!qf_inums[type]) | 5702 | if (!qf_inums[type]) |
5681 | return -EPERM; | 5703 | return -EPERM; |
5682 | 5704 | ||
5683 | qf_inode = ext4_iget(sb, qf_inums[type]); | 5705 | qf_inode = ext4_iget(sb, qf_inums[type], EXT4_IGET_SPECIAL); |
5684 | if (IS_ERR(qf_inode)) { | 5706 | if (IS_ERR(qf_inode)) { |
5685 | ext4_error(sb, "Bad quota inode # %lu", qf_inums[type]); | 5707 | ext4_error(sb, "Bad quota inode # %lu", qf_inums[type]); |
5686 | return PTR_ERR(qf_inode); | 5708 | return PTR_ERR(qf_inode); |
@@ -5690,9 +5712,9 @@ static int ext4_quota_enable(struct super_block *sb, int type, int format_id, | |||
5690 | qf_inode->i_flags |= S_NOQUOTA; | 5712 | qf_inode->i_flags |= S_NOQUOTA; |
5691 | lockdep_set_quota_inode(qf_inode, I_DATA_SEM_QUOTA); | 5713 | lockdep_set_quota_inode(qf_inode, I_DATA_SEM_QUOTA); |
5692 | err = dquot_enable(qf_inode, type, format_id, flags); | 5714 | err = dquot_enable(qf_inode, type, format_id, flags); |
5693 | iput(qf_inode); | ||
5694 | if (err) | 5715 | if (err) |
5695 | lockdep_set_quota_inode(qf_inode, I_DATA_SEM_NORMAL); | 5716 | lockdep_set_quota_inode(qf_inode, I_DATA_SEM_NORMAL); |
5717 | iput(qf_inode); | ||
5696 | 5718 | ||
5697 | return err; | 5719 | return err; |
5698 | } | 5720 | } |
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index 7643d52c776c..86ed9c686249 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c | |||
@@ -384,7 +384,7 @@ static int ext4_xattr_inode_iget(struct inode *parent, unsigned long ea_ino, | |||
384 | struct inode *inode; | 384 | struct inode *inode; |
385 | int err; | 385 | int err; |
386 | 386 | ||
387 | inode = ext4_iget(parent->i_sb, ea_ino); | 387 | inode = ext4_iget(parent->i_sb, ea_ino, EXT4_IGET_NORMAL); |
388 | if (IS_ERR(inode)) { | 388 | if (IS_ERR(inode)) { |
389 | err = PTR_ERR(inode); | 389 | err = PTR_ERR(inode); |
390 | ext4_error(parent->i_sb, | 390 | ext4_error(parent->i_sb, |
@@ -522,14 +522,13 @@ ext4_xattr_block_get(struct inode *inode, int name_index, const char *name, | |||
522 | ea_idebug(inode, "name=%d.%s, buffer=%p, buffer_size=%ld", | 522 | ea_idebug(inode, "name=%d.%s, buffer=%p, buffer_size=%ld", |
523 | name_index, name, buffer, (long)buffer_size); | 523 | name_index, name, buffer, (long)buffer_size); |
524 | 524 | ||
525 | error = -ENODATA; | ||
526 | if (!EXT4_I(inode)->i_file_acl) | 525 | if (!EXT4_I(inode)->i_file_acl) |
527 | goto cleanup; | 526 | return -ENODATA; |
528 | ea_idebug(inode, "reading block %llu", | 527 | ea_idebug(inode, "reading block %llu", |
529 | (unsigned long long)EXT4_I(inode)->i_file_acl); | 528 | (unsigned long long)EXT4_I(inode)->i_file_acl); |
530 | bh = sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl); | 529 | bh = ext4_sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl, REQ_PRIO); |
531 | if (!bh) | 530 | if (IS_ERR(bh)) |
532 | goto cleanup; | 531 | return PTR_ERR(bh); |
533 | ea_bdebug(bh, "b_count=%d, refcount=%d", | 532 | ea_bdebug(bh, "b_count=%d, refcount=%d", |
534 | atomic_read(&(bh->b_count)), le32_to_cpu(BHDR(bh)->h_refcount)); | 533 | atomic_read(&(bh->b_count)), le32_to_cpu(BHDR(bh)->h_refcount)); |
535 | error = ext4_xattr_check_block(inode, bh); | 534 | error = ext4_xattr_check_block(inode, bh); |
@@ -696,26 +695,23 @@ ext4_xattr_block_list(struct dentry *dentry, char *buffer, size_t buffer_size) | |||
696 | ea_idebug(inode, "buffer=%p, buffer_size=%ld", | 695 | ea_idebug(inode, "buffer=%p, buffer_size=%ld", |
697 | buffer, (long)buffer_size); | 696 | buffer, (long)buffer_size); |
698 | 697 | ||
699 | error = 0; | ||
700 | if (!EXT4_I(inode)->i_file_acl) | 698 | if (!EXT4_I(inode)->i_file_acl) |
701 | goto cleanup; | 699 | return 0; |
702 | ea_idebug(inode, "reading block %llu", | 700 | ea_idebug(inode, "reading block %llu", |
703 | (unsigned long long)EXT4_I(inode)->i_file_acl); | 701 | (unsigned long long)EXT4_I(inode)->i_file_acl); |
704 | bh = sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl); | 702 | bh = ext4_sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl, REQ_PRIO); |
705 | error = -EIO; | 703 | if (IS_ERR(bh)) |
706 | if (!bh) | 704 | return PTR_ERR(bh); |
707 | goto cleanup; | ||
708 | ea_bdebug(bh, "b_count=%d, refcount=%d", | 705 | ea_bdebug(bh, "b_count=%d, refcount=%d", |
709 | atomic_read(&(bh->b_count)), le32_to_cpu(BHDR(bh)->h_refcount)); | 706 | atomic_read(&(bh->b_count)), le32_to_cpu(BHDR(bh)->h_refcount)); |
710 | error = ext4_xattr_check_block(inode, bh); | 707 | error = ext4_xattr_check_block(inode, bh); |
711 | if (error) | 708 | if (error) |
712 | goto cleanup; | 709 | goto cleanup; |
713 | ext4_xattr_block_cache_insert(EA_BLOCK_CACHE(inode), bh); | 710 | ext4_xattr_block_cache_insert(EA_BLOCK_CACHE(inode), bh); |
714 | error = ext4_xattr_list_entries(dentry, BFIRST(bh), buffer, buffer_size); | 711 | error = ext4_xattr_list_entries(dentry, BFIRST(bh), buffer, |
715 | 712 | buffer_size); | |
716 | cleanup: | 713 | cleanup: |
717 | brelse(bh); | 714 | brelse(bh); |
718 | |||
719 | return error; | 715 | return error; |
720 | } | 716 | } |
721 | 717 | ||
@@ -830,9 +826,9 @@ int ext4_get_inode_usage(struct inode *inode, qsize_t *usage) | |||
830 | } | 826 | } |
831 | 827 | ||
832 | if (EXT4_I(inode)->i_file_acl) { | 828 | if (EXT4_I(inode)->i_file_acl) { |
833 | bh = sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl); | 829 | bh = ext4_sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl, REQ_PRIO); |
834 | if (!bh) { | 830 | if (IS_ERR(bh)) { |
835 | ret = -EIO; | 831 | ret = PTR_ERR(bh); |
836 | goto out; | 832 | goto out; |
837 | } | 833 | } |
838 | 834 | ||
@@ -1486,7 +1482,8 @@ ext4_xattr_inode_cache_find(struct inode *inode, const void *value, | |||
1486 | } | 1482 | } |
1487 | 1483 | ||
1488 | while (ce) { | 1484 | while (ce) { |
1489 | ea_inode = ext4_iget(inode->i_sb, ce->e_value); | 1485 | ea_inode = ext4_iget(inode->i_sb, ce->e_value, |
1486 | EXT4_IGET_NORMAL); | ||
1490 | if (!IS_ERR(ea_inode) && | 1487 | if (!IS_ERR(ea_inode) && |
1491 | !is_bad_inode(ea_inode) && | 1488 | !is_bad_inode(ea_inode) && |
1492 | (EXT4_I(ea_inode)->i_flags & EXT4_EA_INODE_FL) && | 1489 | (EXT4_I(ea_inode)->i_flags & EXT4_EA_INODE_FL) && |
@@ -1821,16 +1818,15 @@ ext4_xattr_block_find(struct inode *inode, struct ext4_xattr_info *i, | |||
1821 | 1818 | ||
1822 | if (EXT4_I(inode)->i_file_acl) { | 1819 | if (EXT4_I(inode)->i_file_acl) { |
1823 | /* The inode already has an extended attribute block. */ | 1820 | /* The inode already has an extended attribute block. */ |
1824 | bs->bh = sb_bread(sb, EXT4_I(inode)->i_file_acl); | 1821 | bs->bh = ext4_sb_bread(sb, EXT4_I(inode)->i_file_acl, REQ_PRIO); |
1825 | error = -EIO; | 1822 | if (IS_ERR(bs->bh)) |
1826 | if (!bs->bh) | 1823 | return PTR_ERR(bs->bh); |
1827 | goto cleanup; | ||
1828 | ea_bdebug(bs->bh, "b_count=%d, refcount=%d", | 1824 | ea_bdebug(bs->bh, "b_count=%d, refcount=%d", |
1829 | atomic_read(&(bs->bh->b_count)), | 1825 | atomic_read(&(bs->bh->b_count)), |
1830 | le32_to_cpu(BHDR(bs->bh)->h_refcount)); | 1826 | le32_to_cpu(BHDR(bs->bh)->h_refcount)); |
1831 | error = ext4_xattr_check_block(inode, bs->bh); | 1827 | error = ext4_xattr_check_block(inode, bs->bh); |
1832 | if (error) | 1828 | if (error) |
1833 | goto cleanup; | 1829 | return error; |
1834 | /* Find the named attribute. */ | 1830 | /* Find the named attribute. */ |
1835 | bs->s.base = BHDR(bs->bh); | 1831 | bs->s.base = BHDR(bs->bh); |
1836 | bs->s.first = BFIRST(bs->bh); | 1832 | bs->s.first = BFIRST(bs->bh); |
@@ -1839,13 +1835,10 @@ ext4_xattr_block_find(struct inode *inode, struct ext4_xattr_info *i, | |||
1839 | error = xattr_find_entry(inode, &bs->s.here, bs->s.end, | 1835 | error = xattr_find_entry(inode, &bs->s.here, bs->s.end, |
1840 | i->name_index, i->name, 1); | 1836 | i->name_index, i->name, 1); |
1841 | if (error && error != -ENODATA) | 1837 | if (error && error != -ENODATA) |
1842 | goto cleanup; | 1838 | return error; |
1843 | bs->s.not_found = error; | 1839 | bs->s.not_found = error; |
1844 | } | 1840 | } |
1845 | error = 0; | 1841 | return 0; |
1846 | |||
1847 | cleanup: | ||
1848 | return error; | ||
1849 | } | 1842 | } |
1850 | 1843 | ||
1851 | static int | 1844 | static int |
@@ -2274,9 +2267,9 @@ static struct buffer_head *ext4_xattr_get_block(struct inode *inode) | |||
2274 | 2267 | ||
2275 | if (!EXT4_I(inode)->i_file_acl) | 2268 | if (!EXT4_I(inode)->i_file_acl) |
2276 | return NULL; | 2269 | return NULL; |
2277 | bh = sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl); | 2270 | bh = ext4_sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl, REQ_PRIO); |
2278 | if (!bh) | 2271 | if (IS_ERR(bh)) |
2279 | return ERR_PTR(-EIO); | 2272 | return bh; |
2280 | error = ext4_xattr_check_block(inode, bh); | 2273 | error = ext4_xattr_check_block(inode, bh); |
2281 | if (error) { | 2274 | if (error) { |
2282 | brelse(bh); | 2275 | brelse(bh); |
@@ -2729,7 +2722,7 @@ retry: | |||
2729 | base = IFIRST(header); | 2722 | base = IFIRST(header); |
2730 | end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size; | 2723 | end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size; |
2731 | min_offs = end - base; | 2724 | min_offs = end - base; |
2732 | total_ino = sizeof(struct ext4_xattr_ibody_header); | 2725 | total_ino = sizeof(struct ext4_xattr_ibody_header) + sizeof(u32); |
2733 | 2726 | ||
2734 | error = xattr_check_inode(inode, header, end); | 2727 | error = xattr_check_inode(inode, header, end); |
2735 | if (error) | 2728 | if (error) |
@@ -2746,10 +2739,11 @@ retry: | |||
2746 | if (EXT4_I(inode)->i_file_acl) { | 2739 | if (EXT4_I(inode)->i_file_acl) { |
2747 | struct buffer_head *bh; | 2740 | struct buffer_head *bh; |
2748 | 2741 | ||
2749 | bh = sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl); | 2742 | bh = ext4_sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl, REQ_PRIO); |
2750 | error = -EIO; | 2743 | if (IS_ERR(bh)) { |
2751 | if (!bh) | 2744 | error = PTR_ERR(bh); |
2752 | goto cleanup; | 2745 | goto cleanup; |
2746 | } | ||
2753 | error = ext4_xattr_check_block(inode, bh); | 2747 | error = ext4_xattr_check_block(inode, bh); |
2754 | if (error) { | 2748 | if (error) { |
2755 | brelse(bh); | 2749 | brelse(bh); |
@@ -2903,11 +2897,12 @@ int ext4_xattr_delete_inode(handle_t *handle, struct inode *inode, | |||
2903 | } | 2897 | } |
2904 | 2898 | ||
2905 | if (EXT4_I(inode)->i_file_acl) { | 2899 | if (EXT4_I(inode)->i_file_acl) { |
2906 | bh = sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl); | 2900 | bh = ext4_sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl, REQ_PRIO); |
2907 | if (!bh) { | 2901 | if (IS_ERR(bh)) { |
2908 | EXT4_ERROR_INODE(inode, "block %llu read error", | 2902 | error = PTR_ERR(bh); |
2909 | EXT4_I(inode)->i_file_acl); | 2903 | if (error == -EIO) |
2910 | error = -EIO; | 2904 | EXT4_ERROR_INODE(inode, "block %llu read error", |
2905 | EXT4_I(inode)->i_file_acl); | ||
2911 | goto cleanup; | 2906 | goto cleanup; |
2912 | } | 2907 | } |
2913 | error = ext4_xattr_check_block(inode, bh); | 2908 | error = ext4_xattr_check_block(inode, bh); |
@@ -3060,8 +3055,10 @@ ext4_xattr_block_cache_find(struct inode *inode, | |||
3060 | while (ce) { | 3055 | while (ce) { |
3061 | struct buffer_head *bh; | 3056 | struct buffer_head *bh; |
3062 | 3057 | ||
3063 | bh = sb_bread(inode->i_sb, ce->e_value); | 3058 | bh = ext4_sb_bread(inode->i_sb, ce->e_value, REQ_PRIO); |
3064 | if (!bh) { | 3059 | if (IS_ERR(bh)) { |
3060 | if (PTR_ERR(bh) == -ENOMEM) | ||
3061 | return NULL; | ||
3065 | EXT4_ERROR_INODE(inode, "block %lu read error", | 3062 | EXT4_ERROR_INODE(inode, "block %lu read error", |
3066 | (unsigned long)ce->e_value); | 3063 | (unsigned long)ce->e_value); |
3067 | } else if (ext4_xattr_cmp(header, BHDR(bh)) == 0) { | 3064 | } else if (ext4_xattr_cmp(header, BHDR(bh)) == 0) { |
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index 150cc030b4d7..2eb55c3361a8 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c | |||
@@ -439,6 +439,8 @@ void jbd2_journal_commit_transaction(journal_t *journal) | |||
439 | finish_wait(&journal->j_wait_updates, &wait); | 439 | finish_wait(&journal->j_wait_updates, &wait); |
440 | } | 440 | } |
441 | spin_unlock(&commit_transaction->t_handle_lock); | 441 | spin_unlock(&commit_transaction->t_handle_lock); |
442 | commit_transaction->t_state = T_SWITCH; | ||
443 | write_unlock(&journal->j_state_lock); | ||
442 | 444 | ||
443 | J_ASSERT (atomic_read(&commit_transaction->t_outstanding_credits) <= | 445 | J_ASSERT (atomic_read(&commit_transaction->t_outstanding_credits) <= |
444 | journal->j_max_transaction_buffers); | 446 | journal->j_max_transaction_buffers); |
@@ -505,6 +507,7 @@ void jbd2_journal_commit_transaction(journal_t *journal) | |||
505 | atomic_sub(atomic_read(&journal->j_reserved_credits), | 507 | atomic_sub(atomic_read(&journal->j_reserved_credits), |
506 | &commit_transaction->t_outstanding_credits); | 508 | &commit_transaction->t_outstanding_credits); |
507 | 509 | ||
510 | write_lock(&journal->j_state_lock); | ||
508 | trace_jbd2_commit_flushing(journal, commit_transaction); | 511 | trace_jbd2_commit_flushing(journal, commit_transaction); |
509 | stats.run.rs_flushing = jiffies; | 512 | stats.run.rs_flushing = jiffies; |
510 | stats.run.rs_locked = jbd2_time_diff(stats.run.rs_locked, | 513 | stats.run.rs_locked = jbd2_time_diff(stats.run.rs_locked, |
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index c0b66a7a795b..cc35537232f2 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c | |||
@@ -138,9 +138,9 @@ static inline void update_t_max_wait(transaction_t *transaction, | |||
138 | } | 138 | } |
139 | 139 | ||
140 | /* | 140 | /* |
141 | * Wait until running transaction passes T_LOCKED state. Also starts the commit | 141 | * Wait until running transaction passes to T_FLUSH state and new transaction |
142 | * if needed. The function expects running transaction to exist and releases | 142 | * can thus be started. Also starts the commit if needed. The function expects |
143 | * j_state_lock. | 143 | * running transaction to exist and releases j_state_lock. |
144 | */ | 144 | */ |
145 | static void wait_transaction_locked(journal_t *journal) | 145 | static void wait_transaction_locked(journal_t *journal) |
146 | __releases(journal->j_state_lock) | 146 | __releases(journal->j_state_lock) |
@@ -160,6 +160,32 @@ static void wait_transaction_locked(journal_t *journal) | |||
160 | finish_wait(&journal->j_wait_transaction_locked, &wait); | 160 | finish_wait(&journal->j_wait_transaction_locked, &wait); |
161 | } | 161 | } |
162 | 162 | ||
163 | /* | ||
164 | * Wait until running transaction transitions from T_SWITCH to T_FLUSH | ||
165 | * state and new transaction can thus be started. The function releases | ||
166 | * j_state_lock. | ||
167 | */ | ||
168 | static void wait_transaction_switching(journal_t *journal) | ||
169 | __releases(journal->j_state_lock) | ||
170 | { | ||
171 | DEFINE_WAIT(wait); | ||
172 | |||
173 | if (WARN_ON(!journal->j_running_transaction || | ||
174 | journal->j_running_transaction->t_state != T_SWITCH)) | ||
175 | return; | ||
176 | prepare_to_wait(&journal->j_wait_transaction_locked, &wait, | ||
177 | TASK_UNINTERRUPTIBLE); | ||
178 | read_unlock(&journal->j_state_lock); | ||
179 | /* | ||
180 | * We don't call jbd2_might_wait_for_commit() here as there's no | ||
181 | * waiting for outstanding handles happening anymore in T_SWITCH state | ||
182 | * and handling of reserved handles actually relies on that for | ||
183 | * correctness. | ||
184 | */ | ||
185 | schedule(); | ||
186 | finish_wait(&journal->j_wait_transaction_locked, &wait); | ||
187 | } | ||
188 | |||
163 | static void sub_reserved_credits(journal_t *journal, int blocks) | 189 | static void sub_reserved_credits(journal_t *journal, int blocks) |
164 | { | 190 | { |
165 | atomic_sub(blocks, &journal->j_reserved_credits); | 191 | atomic_sub(blocks, &journal->j_reserved_credits); |
@@ -183,7 +209,8 @@ static int add_transaction_credits(journal_t *journal, int blocks, | |||
183 | * If the current transaction is locked down for commit, wait | 209 | * If the current transaction is locked down for commit, wait |
184 | * for the lock to be released. | 210 | * for the lock to be released. |
185 | */ | 211 | */ |
186 | if (t->t_state == T_LOCKED) { | 212 | if (t->t_state != T_RUNNING) { |
213 | WARN_ON_ONCE(t->t_state >= T_FLUSH); | ||
187 | wait_transaction_locked(journal); | 214 | wait_transaction_locked(journal); |
188 | return 1; | 215 | return 1; |
189 | } | 216 | } |
@@ -360,8 +387,14 @@ repeat: | |||
360 | /* | 387 | /* |
361 | * We have handle reserved so we are allowed to join T_LOCKED | 388 | * We have handle reserved so we are allowed to join T_LOCKED |
362 | * transaction and we don't have to check for transaction size | 389 | * transaction and we don't have to check for transaction size |
363 | * and journal space. | 390 | * and journal space. But we still have to wait while running |
391 | * transaction is being switched to a committing one as it | ||
392 | * won't wait for any handles anymore. | ||
364 | */ | 393 | */ |
394 | if (transaction->t_state == T_SWITCH) { | ||
395 | wait_transaction_switching(journal); | ||
396 | goto repeat; | ||
397 | } | ||
365 | sub_reserved_credits(journal, blocks); | 398 | sub_reserved_credits(journal, blocks); |
366 | handle->h_reserved = 0; | 399 | handle->h_reserved = 0; |
367 | } | 400 | } |
@@ -910,7 +943,7 @@ repeat: | |||
910 | * this is the first time this transaction is touching this buffer, | 943 | * this is the first time this transaction is touching this buffer, |
911 | * reset the modified flag | 944 | * reset the modified flag |
912 | */ | 945 | */ |
913 | jh->b_modified = 0; | 946 | jh->b_modified = 0; |
914 | 947 | ||
915 | /* | 948 | /* |
916 | * If the buffer is not journaled right now, we need to make sure it | 949 | * If the buffer is not journaled right now, we need to make sure it |