mirror of
https://github.com/torvalds/linux
synced 2024-11-05 18:23:50 +00:00
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:
parent
bb491ce67a
commit
fffb64127a
3 changed files with 14 additions and 31 deletions
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue