diff options
author | Andreas Gruenbacher <agruenba@redhat.com> | 2018-07-25 18:45:08 +0100 |
---|---|---|
committer | Andreas Gruenbacher <agruenba@redhat.com> | 2018-07-25 22:56:14 +0200 |
commit | 776125785a87ff05d49938bd5b9f336f2a05bff6 (patch) | |
tree | bba6683dd63e2daa3f0b32d67af0132e3b7aa328 /fs/gfs2 | |
parent | f6753df35c32f17b7abf0de37aa52850ca9733c9 (diff) | |
download | op-kernel-dev-776125785a87ff05d49938bd5b9f336f2a05bff6.zip op-kernel-dev-776125785a87ff05d49938bd5b9f336f2a05bff6.tar.gz |
gfs2: Special-case rindex for gfs2_grow
To speed up the common case of appending to a file,
gfs2_write_alloc_required presumes that writing beyond the end of a file
will always require additional blocks to be allocated. This assumption
is incorrect for preallocates files, but there are no negative
consequences as long as *some* space is still left on the filesystem.
One special file that always has some space preallocated beyond the end
of the file is the rindex: when growing a filesystem, gfs2_grow adds one
or more new resource groups and appends records describing those
resource groups to the rindex; the preallocated space ensures that this
is always possible.
However, when a filesystem is completely full, gfs2_write_alloc_required
will indicate that an additional allocation is required, and appending
the next record to the rindex will fail even though space for that
record has already been preallocated. To fix that, skip the incorrect
optimization in gfs2_write_alloc_required, but for the rindex only.
Other writes to preallocated space beyond the end of the file are still
allowed to fail on completely full filesystems.
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Reviewed-by: Bob Peterson <rpeterso@redhat.com>
Diffstat (limited to 'fs/gfs2')
-rw-r--r-- | fs/gfs2/bmap.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index 89f1f7d..03128ed 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c @@ -2316,7 +2316,7 @@ int gfs2_write_alloc_required(struct gfs2_inode *ip, u64 offset, end_of_file = (i_size_read(&ip->i_inode) + sdp->sd_sb.sb_bsize - 1) >> shift; lblock = offset >> shift; lblock_stop = (offset + len + sdp->sd_sb.sb_bsize - 1) >> shift; - if (lblock_stop > end_of_file) + if (lblock_stop > end_of_file && ip != GFS2_I(sdp->sd_rindex)) return 1; size = (lblock_stop - lblock) << shift; |