diff options
author | Eric Whitney <enwlinux@gmail.com> | 2018-10-01 14:24:08 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2018-10-01 14:24:08 -0400 |
commit | b6bf9171ef5c37b66d446378ba63af5339a56a97 (patch) | |
tree | 7e82ed99dbf97e0516ef5aaf4064f76e7cb0d04f /fs/ext4/extents_status.h | |
parent | 0b02f4c0d6d9e2c611dfbdd4317193e9dca740e6 (diff) |
ext4: reduce reserved cluster count by number of allocated clusters
Ext4 does not always reduce the reserved cluster count by the number
of clusters allocated when mapping a delayed extent. It sometimes
adds back one or more clusters after allocation if delalloc blocks
adjacent to the range allocated by ext4_ext_map_blocks() share the
clusters newly allocated for that range. However, this overcounts
the number of clusters needed to satisfy future mapping requests
(holding one or more reservations for clusters that have already been
allocated) and premature ENOSPC and quota failures, etc., result.
Ext4 also does not reduce the reserved cluster count when allocating
clusters for non-delayed allocated writes that have previously been
reserved for delayed writes. This also results in overcounts.
To make it possible to handle reserved cluster accounting for
fallocated regions in the same manner as used for other non-delayed
writes, do the reserved cluster accounting for them at the time of
allocation. In the current code, this is only done later when a
delayed extent sharing the fallocated region is finally mapped.
Address comment correcting handling of unsigned long long constant
from Jan Kara's review of RFC version of this patch.
Signed-off-by: Eric Whitney <enwlinux@gmail.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Diffstat (limited to 'fs/ext4/extents_status.h')
-rw-r--r-- | fs/ext4/extents_status.h | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/fs/ext4/extents_status.h b/fs/ext4/extents_status.h index 9d3c676ec623..131a8b7df265 100644 --- a/fs/ext4/extents_status.h +++ b/fs/ext4/extents_status.h @@ -244,5 +244,9 @@ extern void ext4_remove_pending(struct inode *inode, ext4_lblk_t lblk); extern bool ext4_is_pending(struct inode *inode, ext4_lblk_t lblk); extern int ext4_es_insert_delayed_block(struct inode *inode, ext4_lblk_t lblk, bool allocated); +extern unsigned int ext4_es_delayed_clu(struct inode *inode, ext4_lblk_t lblk, + ext4_lblk_t len); +extern void ext4_es_remove_blks(struct inode *inode, ext4_lblk_t lblk, + ext4_lblk_t len); #endif /* _EXT4_EXTENTS_STATUS_H */ |