summaryrefslogtreecommitdiff
path: root/fs/gfs2/file.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-04-04 13:09:42 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2018-04-04 13:09:42 -0700
commit2bd99df54f43b659ddaab8922adbaf3bcf3753ed (patch)
tree5a12962375b3b755f3b8b8420490f0275858dcf2 /fs/gfs2/file.c
parent94514bbe9e5c402c4232af158a295a8fdfd72a2c (diff)
parent5e86d9d122d0d6fae00d9dff41c22d6f4d09f566 (diff)
Merge tag 'gfs2-4.17.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2
Pull gfs2 updates from Bob Peterson: "We've only got nine GFS2 patches for this merge window: - report journal recovery times more accurately during journal replay (Abhi Das) - fix fallocate chunk size (Andreas Gruenbacher) - correctly dirty inodes during rename (Andreas Gruenbacher) - improve the comment for function gfs2_block_map (Andreas Gruenbacher) - improve kernel trace point iomap end: The physical block address was added (Andreas Gruenbacher) - fix a nasty file system corruption bug that surfaced in xfstests 476 in punch-hole/truncate (Andreas Gruenbacher) - fix a problem Christoph Helwig pointed out, namely, that GFS2 was misusing the IOMAP_ZERO flag. The zeroing of new blocks was moved to the proper fallocate code (Andreas Gruenbacher) - declare function gfs2_remove_from_ail as static (Bob Peterson) - only set PageChecked for jdata page writes (Bob Peterson)" * tag 'gfs2-4.17.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2: gfs2: time journal recovery steps accurately gfs2: Zero out fallocated blocks in fallocate_chunk gfs2: Check for the end of metadata in punch_hole gfs2: gfs2_iomap_end tracepoint: log block address gfs2: Improve gfs2_block_map comment GFS2: Only set PageChecked for jdata pages GFS2: Make function gfs2_remove_from_ail static gfs2: Dirty source inode during rename gfs2: Fix fallocate chunk size
Diffstat (limited to 'fs/gfs2/file.c')
-rw-r--r--fs/gfs2/file.c34
1 files changed, 17 insertions, 17 deletions
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c
index 4f88e201b3f0..4b71f021a9e2 100644
--- a/fs/gfs2/file.c
+++ b/fs/gfs2/file.c
@@ -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;
}
}
@@ -809,7 +808,7 @@ static long __gfs2_fallocate(struct file *file, int mode, loff_t offset, loff_t
struct gfs2_inode *ip = GFS2_I(inode);
struct gfs2_alloc_parms ap = { .aflags = 0, };
unsigned int data_blocks = 0, ind_blocks = 0, rblocks;
- loff_t bytes, max_bytes, max_blks = UINT_MAX;
+ loff_t bytes, max_bytes, max_blks;
int error;
const loff_t pos = offset;
const loff_t count = len;
@@ -861,7 +860,8 @@ static long __gfs2_fallocate(struct file *file, int mode, loff_t offset, loff_t
return error;
/* ap.allowed tells us how many blocks quota will allow
* us to write. Check if this reduces max_blks */
- if (ap.allowed && ap.allowed < max_blks)
+ max_blks = UINT_MAX;
+ if (ap.allowed)
max_blks = ap.allowed;
error = gfs2_inplace_reserve(ip, &ap);