diff options
-rw-r--r-- | fs/ext4/extents.c | 2 | ||||
-rw-r--r-- | fs/ext4/indirect.c | 2 | ||||
-rw-r--r-- | fs/ext4/inode.c | 10 | ||||
-rw-r--r-- | fs/ext4/namei.c | 2 | ||||
-rw-r--r-- | fs/ext4/super.c | 8 |
5 files changed, 17 insertions, 7 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 1ba8b4ab03a8..d86d2622f826 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
@@ -4456,6 +4456,8 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode, | |||
4456 | ar.flags |= EXT4_MB_HINT_NOPREALLOC; | 4456 | ar.flags |= EXT4_MB_HINT_NOPREALLOC; |
4457 | if (flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE) | 4457 | if (flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE) |
4458 | ar.flags |= EXT4_MB_DELALLOC_RESERVED; | 4458 | ar.flags |= EXT4_MB_DELALLOC_RESERVED; |
4459 | if (flags & EXT4_GET_BLOCKS_METADATA_NOFAIL) | ||
4460 | ar.flags |= EXT4_MB_USE_RESERVED; | ||
4459 | newblock = ext4_mb_new_blocks(handle, &ar, &err); | 4461 | newblock = ext4_mb_new_blocks(handle, &ar, &err); |
4460 | if (!newblock) | 4462 | if (!newblock) |
4461 | goto out2; | 4463 | goto out2; |
diff --git a/fs/ext4/indirect.c b/fs/ext4/indirect.c index 958824019509..9962d577bad5 100644 --- a/fs/ext4/indirect.c +++ b/fs/ext4/indirect.c | |||
@@ -576,6 +576,8 @@ int ext4_ind_map_blocks(handle_t *handle, struct inode *inode, | |||
576 | ar.flags = EXT4_MB_HINT_DATA; | 576 | ar.flags = EXT4_MB_HINT_DATA; |
577 | if (flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE) | 577 | if (flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE) |
578 | ar.flags |= EXT4_MB_DELALLOC_RESERVED; | 578 | ar.flags |= EXT4_MB_DELALLOC_RESERVED; |
579 | if (flags & EXT4_GET_BLOCKS_METADATA_NOFAIL) | ||
580 | ar.flags |= EXT4_MB_USE_RESERVED; | ||
579 | 581 | ||
580 | ar.goal = ext4_find_goal(inode, map->m_lblk, partial); | 582 | ar.goal = ext4_find_goal(inode, map->m_lblk, partial); |
581 | 583 | ||
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 263a46c488c7..e8a67b8ba90c 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -731,18 +731,18 @@ int ext4_get_block(struct inode *inode, sector_t iblock, | |||
731 | * `handle' can be NULL if create is zero | 731 | * `handle' can be NULL if create is zero |
732 | */ | 732 | */ |
733 | struct buffer_head *ext4_getblk(handle_t *handle, struct inode *inode, | 733 | struct buffer_head *ext4_getblk(handle_t *handle, struct inode *inode, |
734 | ext4_lblk_t block, int create) | 734 | ext4_lblk_t block, int map_flags) |
735 | { | 735 | { |
736 | struct ext4_map_blocks map; | 736 | struct ext4_map_blocks map; |
737 | struct buffer_head *bh; | 737 | struct buffer_head *bh; |
738 | int create = map_flags & EXT4_GET_BLOCKS_CREATE; | ||
738 | int err; | 739 | int err; |
739 | 740 | ||
740 | J_ASSERT(handle != NULL || create == 0); | 741 | J_ASSERT(handle != NULL || create == 0); |
741 | 742 | ||
742 | map.m_lblk = block; | 743 | map.m_lblk = block; |
743 | map.m_len = 1; | 744 | map.m_len = 1; |
744 | err = ext4_map_blocks(handle, inode, &map, | 745 | err = ext4_map_blocks(handle, inode, &map, map_flags); |
745 | create ? EXT4_GET_BLOCKS_CREATE : 0); | ||
746 | 746 | ||
747 | if (err == 0) | 747 | if (err == 0) |
748 | return create ? ERR_PTR(-ENOSPC) : NULL; | 748 | return create ? ERR_PTR(-ENOSPC) : NULL; |
@@ -788,11 +788,11 @@ errout: | |||
788 | } | 788 | } |
789 | 789 | ||
790 | struct buffer_head *ext4_bread(handle_t *handle, struct inode *inode, | 790 | struct buffer_head *ext4_bread(handle_t *handle, struct inode *inode, |
791 | ext4_lblk_t block, int create) | 791 | ext4_lblk_t block, int map_flags) |
792 | { | 792 | { |
793 | struct buffer_head *bh; | 793 | struct buffer_head *bh; |
794 | 794 | ||
795 | bh = ext4_getblk(handle, inode, block, create); | 795 | bh = ext4_getblk(handle, inode, block, map_flags); |
796 | if (IS_ERR(bh)) | 796 | if (IS_ERR(bh)) |
797 | return bh; | 797 | return bh; |
798 | if (!bh || buffer_uptodate(bh)) | 798 | if (!bh || buffer_uptodate(bh)) |
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 5e7676f1e82f..e230b31251f7 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c | |||
@@ -61,7 +61,7 @@ static struct buffer_head *ext4_append(handle_t *handle, | |||
61 | 61 | ||
62 | *block = inode->i_size >> inode->i_sb->s_blocksize_bits; | 62 | *block = inode->i_size >> inode->i_sb->s_blocksize_bits; |
63 | 63 | ||
64 | bh = ext4_bread(handle, inode, *block, 1); | 64 | bh = ext4_bread(handle, inode, *block, EXT4_GET_BLOCKS_CREATE); |
65 | if (IS_ERR(bh)) | 65 | if (IS_ERR(bh)) |
66 | return bh; | 66 | return bh; |
67 | inode->i_size += inode->i_sb->s_blocksize; | 67 | inode->i_size += inode->i_sb->s_blocksize; |
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 2858ac09f5a3..bd4df9d379b2 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -5438,6 +5438,7 @@ static ssize_t ext4_quota_write(struct super_block *sb, int type, | |||
5438 | struct inode *inode = sb_dqopt(sb)->files[type]; | 5438 | struct inode *inode = sb_dqopt(sb)->files[type]; |
5439 | ext4_lblk_t blk = off >> EXT4_BLOCK_SIZE_BITS(sb); | 5439 | ext4_lblk_t blk = off >> EXT4_BLOCK_SIZE_BITS(sb); |
5440 | int err, offset = off & (sb->s_blocksize - 1); | 5440 | int err, offset = off & (sb->s_blocksize - 1); |
5441 | int retries = 0; | ||
5441 | struct buffer_head *bh; | 5442 | struct buffer_head *bh; |
5442 | handle_t *handle = journal_current_handle(); | 5443 | handle_t *handle = journal_current_handle(); |
5443 | 5444 | ||
@@ -5458,7 +5459,12 @@ static ssize_t ext4_quota_write(struct super_block *sb, int type, | |||
5458 | return -EIO; | 5459 | return -EIO; |
5459 | } | 5460 | } |
5460 | 5461 | ||
5461 | bh = ext4_bread(handle, inode, blk, 1); | 5462 | do { |
5463 | bh = ext4_bread(handle, inode, blk, | ||
5464 | EXT4_GET_BLOCKS_CREATE | | ||
5465 | EXT4_GET_BLOCKS_METADATA_NOFAIL); | ||
5466 | } while (IS_ERR(bh) && (PTR_ERR(bh) == -ENOSPC) && | ||
5467 | ext4_should_retry_alloc(inode->i_sb, &retries)); | ||
5462 | if (IS_ERR(bh)) | 5468 | if (IS_ERR(bh)) |
5463 | return PTR_ERR(bh); | 5469 | return PTR_ERR(bh); |
5464 | if (!bh) | 5470 | if (!bh) |