gfs2: Zero out fallocated blocks in fallocate_chunk

Instead of zeroing out fallocated blocks in gfs2_iomap_alloc, zero them
out in fallocate_chunk, much higher up the call stack.  This gets rid of
gfs2's abuse of the IOMAP_ZERO flag as well as the gfs2 specific zeronew
buffer flag.  I can't think of a reason why zeroing out the blocks in
gfs2_iomap_alloc would have any benefits: there is no additional locking
at that level that would add protection to the newly allocated blocks.

While at it, change fallocate over from gs2_block_map to gfs2_iomap_begin.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Signed-off-by: Bob Peterson <rpeterso@redhat.com>
Acked-by: Christoph Hellwig <hch@lst.de>
This commit is contained in:
Andreas Gruenbacher 2018-03-29 06:50:32 -07:00 committed by Bob Peterson
parent bb491ce67a
commit fffb64127a
3 changed files with 14 additions and 31 deletions

View file

@ -491,14 +491,12 @@ static int gfs2_iomap_alloc(struct inode *inode, struct iomap *iomap,
{
struct gfs2_inode *ip = GFS2_I(inode);
struct gfs2_sbd *sdp = GFS2_SB(inode);
struct super_block *sb = sdp->sd_vfs;
struct buffer_head *dibh = mp->mp_bh[0];
u64 bn;
unsigned n, i, blks, alloced = 0, iblks = 0, branch_start = 0;
unsigned dblks = 0;
unsigned ptrs_per_blk;
const unsigned end_of_metadata = mp->mp_fheight - 1;
int ret;
enum alloc_state state;
__be64 *ptr;
__be64 zero_bn = 0;
@ -607,15 +605,6 @@ static int gfs2_iomap_alloc(struct inode *inode, struct iomap *iomap,
iomap->flags |= IOMAP_F_NEW;
while (n-- > 0)
*ptr++ = cpu_to_be64(bn++);
if (flags & IOMAP_ZERO) {
ret = sb_issue_zeroout(sb, iomap->addr >> inode->i_blkbits,
dblks, GFP_NOFS);
if (ret) {
fs_err(sdp,
"Failed to zero data buffers\n");
flags &= ~IOMAP_ZERO;
}
}
break;
}
} while (iomap->addr == IOMAP_NULL_ADDR);
@ -846,8 +835,6 @@ int gfs2_block_map(struct inode *inode, sector_t lblock,
if (create)
flags |= IOMAP_WRITE;
if (buffer_zeronew(bh_map))
flags |= IOMAP_ZERO;
ret = gfs2_iomap_begin(inode, (loff_t)lblock << inode->i_blkbits,
bh_map->b_size, flags, &iomap);
if (ret) {

View file

@ -729,11 +729,12 @@ static ssize_t gfs2_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
static int fallocate_chunk(struct inode *inode, loff_t offset, loff_t len,
int mode)
{
struct super_block *sb = inode->i_sb;
struct gfs2_inode *ip = GFS2_I(inode);
loff_t end = offset + len;
struct buffer_head *dibh;
struct iomap iomap;
int error;
unsigned int nr_blks;
sector_t lblock = offset >> inode->i_blkbits;
error = gfs2_meta_inode_buffer(ip, &dibh);
if (unlikely(error))
@ -747,21 +748,19 @@ static int fallocate_chunk(struct inode *inode, loff_t offset, loff_t len,
goto out;
}
while (len) {
struct buffer_head bh_map = { .b_state = 0, .b_blocknr = 0 };
bh_map.b_size = len;
set_buffer_zeronew(&bh_map);
error = gfs2_block_map(inode, lblock, &bh_map, 1);
if (unlikely(error))
while (offset < end) {
error = gfs2_iomap_begin(inode, offset, end - offset,
IOMAP_WRITE, &iomap);
if (error)
goto out;
len -= bh_map.b_size;
nr_blks = bh_map.b_size >> inode->i_blkbits;
lblock += nr_blks;
if (!buffer_new(&bh_map))
offset = iomap.offset + iomap.length;
if (iomap.type != IOMAP_HOLE)
continue;
if (unlikely(!buffer_zeronew(&bh_map))) {
error = -EIO;
error = sb_issue_zeroout(sb, iomap.addr >> inode->i_blkbits,
iomap.length >> inode->i_blkbits,
GFP_NOFS);
if (error) {
fs_err(GFS2_SB(inode), "Failed to zero data buffers\n");
goto out;
}
}

View file

@ -130,15 +130,12 @@ static inline bool gfs2_rbm_eq(const struct gfs2_rbm *rbm1,
enum gfs2_state_bits {
BH_Pinned = BH_PrivateStart,
BH_Escaped = BH_PrivateStart + 1,
BH_Zeronew = BH_PrivateStart + 2,
};
BUFFER_FNS(Pinned, pinned)
TAS_BUFFER_FNS(Pinned, pinned)
BUFFER_FNS(Escaped, escaped)
TAS_BUFFER_FNS(Escaped, escaped)
BUFFER_FNS(Zeronew, zeronew)
TAS_BUFFER_FNS(Zeronew, zeronew)
struct gfs2_bufdata {
struct buffer_head *bd_bh;