diff options
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r-- | fs/btrfs/inode.c | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 4e024260ad71..1e861a063721 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -3835,10 +3835,7 @@ cache_acl: | |||
3835 | break; | 3835 | break; |
3836 | case S_IFDIR: | 3836 | case S_IFDIR: |
3837 | inode->i_fop = &btrfs_dir_file_operations; | 3837 | inode->i_fop = &btrfs_dir_file_operations; |
3838 | if (root == fs_info->tree_root) | 3838 | inode->i_op = &btrfs_dir_inode_operations; |
3839 | inode->i_op = &btrfs_dir_ro_inode_operations; | ||
3840 | else | ||
3841 | inode->i_op = &btrfs_dir_inode_operations; | ||
3842 | break; | 3839 | break; |
3843 | case S_IFLNK: | 3840 | case S_IFLNK: |
3844 | inode->i_op = &btrfs_symlink_inode_operations; | 3841 | inode->i_op = &btrfs_symlink_inode_operations; |
@@ -4505,8 +4502,19 @@ search_again: | |||
4505 | if (found_type > min_type) { | 4502 | if (found_type > min_type) { |
4506 | del_item = 1; | 4503 | del_item = 1; |
4507 | } else { | 4504 | } else { |
4508 | if (item_end < new_size) | 4505 | if (item_end < new_size) { |
4506 | /* | ||
4507 | * With NO_HOLES mode, for the following mapping | ||
4508 | * | ||
4509 | * [0-4k][hole][8k-12k] | ||
4510 | * | ||
4511 | * if truncating isize down to 6k, it ends up | ||
4512 | * isize being 8k. | ||
4513 | */ | ||
4514 | if (btrfs_fs_incompat(root->fs_info, NO_HOLES)) | ||
4515 | last_size = new_size; | ||
4509 | break; | 4516 | break; |
4517 | } | ||
4510 | if (found_key.offset >= new_size) | 4518 | if (found_key.offset >= new_size) |
4511 | del_item = 1; | 4519 | del_item = 1; |
4512 | else | 4520 | else |
@@ -5710,6 +5718,7 @@ static struct inode *new_simple_dir(struct super_block *s, | |||
5710 | 5718 | ||
5711 | inode->i_ino = BTRFS_EMPTY_SUBVOL_DIR_OBJECTID; | 5719 | inode->i_ino = BTRFS_EMPTY_SUBVOL_DIR_OBJECTID; |
5712 | inode->i_op = &btrfs_dir_ro_inode_operations; | 5720 | inode->i_op = &btrfs_dir_ro_inode_operations; |
5721 | inode->i_opflags &= ~IOP_XATTR; | ||
5713 | inode->i_fop = &simple_dir_operations; | 5722 | inode->i_fop = &simple_dir_operations; |
5714 | inode->i_mode = S_IFDIR | S_IRUGO | S_IWUSR | S_IXUGO; | 5723 | inode->i_mode = S_IFDIR | S_IRUGO | S_IWUSR | S_IXUGO; |
5715 | inode->i_mtime = current_time(inode); | 5724 | inode->i_mtime = current_time(inode); |
@@ -7215,7 +7224,6 @@ static struct extent_map *btrfs_create_dio_extent(struct inode *inode, | |||
7215 | struct extent_map *em = NULL; | 7224 | struct extent_map *em = NULL; |
7216 | int ret; | 7225 | int ret; |
7217 | 7226 | ||
7218 | down_read(&BTRFS_I(inode)->dio_sem); | ||
7219 | if (type != BTRFS_ORDERED_NOCOW) { | 7227 | if (type != BTRFS_ORDERED_NOCOW) { |
7220 | em = create_pinned_em(inode, start, len, orig_start, | 7228 | em = create_pinned_em(inode, start, len, orig_start, |
7221 | block_start, block_len, orig_block_len, | 7229 | block_start, block_len, orig_block_len, |
@@ -7234,7 +7242,6 @@ static struct extent_map *btrfs_create_dio_extent(struct inode *inode, | |||
7234 | em = ERR_PTR(ret); | 7242 | em = ERR_PTR(ret); |
7235 | } | 7243 | } |
7236 | out: | 7244 | out: |
7237 | up_read(&BTRFS_I(inode)->dio_sem); | ||
7238 | 7245 | ||
7239 | return em; | 7246 | return em; |
7240 | } | 7247 | } |
@@ -8692,6 +8699,7 @@ static ssize_t btrfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter) | |||
8692 | dio_data.unsubmitted_oe_range_start = (u64)offset; | 8699 | dio_data.unsubmitted_oe_range_start = (u64)offset; |
8693 | dio_data.unsubmitted_oe_range_end = (u64)offset; | 8700 | dio_data.unsubmitted_oe_range_end = (u64)offset; |
8694 | current->journal_info = &dio_data; | 8701 | current->journal_info = &dio_data; |
8702 | down_read(&BTRFS_I(inode)->dio_sem); | ||
8695 | } else if (test_bit(BTRFS_INODE_READDIO_NEED_LOCK, | 8703 | } else if (test_bit(BTRFS_INODE_READDIO_NEED_LOCK, |
8696 | &BTRFS_I(inode)->runtime_flags)) { | 8704 | &BTRFS_I(inode)->runtime_flags)) { |
8697 | inode_dio_end(inode); | 8705 | inode_dio_end(inode); |
@@ -8704,6 +8712,7 @@ static ssize_t btrfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter) | |||
8704 | iter, btrfs_get_blocks_direct, NULL, | 8712 | iter, btrfs_get_blocks_direct, NULL, |
8705 | btrfs_submit_direct, flags); | 8713 | btrfs_submit_direct, flags); |
8706 | if (iov_iter_rw(iter) == WRITE) { | 8714 | if (iov_iter_rw(iter) == WRITE) { |
8715 | up_read(&BTRFS_I(inode)->dio_sem); | ||
8707 | current->journal_info = NULL; | 8716 | current->journal_info = NULL; |
8708 | if (ret < 0 && ret != -EIOCBQUEUED) { | 8717 | if (ret < 0 && ret != -EIOCBQUEUED) { |
8709 | if (dio_data.reserve) | 8718 | if (dio_data.reserve) |
@@ -9212,6 +9221,7 @@ static int btrfs_truncate(struct inode *inode) | |||
9212 | break; | 9221 | break; |
9213 | } | 9222 | } |
9214 | 9223 | ||
9224 | btrfs_block_rsv_release(fs_info, rsv, -1); | ||
9215 | ret = btrfs_block_rsv_migrate(&fs_info->trans_block_rsv, | 9225 | ret = btrfs_block_rsv_migrate(&fs_info->trans_block_rsv, |
9216 | rsv, min_size, 0); | 9226 | rsv, min_size, 0); |
9217 | BUG_ON(ret); /* shouldn't happen */ | 9227 | BUG_ON(ret); /* shouldn't happen */ |
@@ -10579,8 +10589,6 @@ static const struct inode_operations btrfs_dir_inode_operations = { | |||
10579 | static const struct inode_operations btrfs_dir_ro_inode_operations = { | 10589 | static const struct inode_operations btrfs_dir_ro_inode_operations = { |
10580 | .lookup = btrfs_lookup, | 10590 | .lookup = btrfs_lookup, |
10581 | .permission = btrfs_permission, | 10591 | .permission = btrfs_permission, |
10582 | .get_acl = btrfs_get_acl, | ||
10583 | .set_acl = btrfs_set_acl, | ||
10584 | .update_time = btrfs_update_time, | 10592 | .update_time = btrfs_update_time, |
10585 | }; | 10593 | }; |
10586 | 10594 | ||