summaryrefslogtreecommitdiffstats
path: root/fs/gfs2/bmap.c
diff options
context:
space:
mode:
authorAndreas Gruenbacher2019-04-30 17:45:34 +0200
committerDarrick J. Wong2019-05-01 16:47:37 +0200
commitdf0db3ecdb8fc942e9d812558b8e15ecd3e050b1 (patch)
tree85e9df7f72f0aba01f16944860f80daf76d272e4 /fs/gfs2/bmap.c
parentiomap: Fix use-after-free error in page_done callback (diff)
downloadkernel-qcow2-linux-df0db3ecdb8fc942e9d812558b8e15ecd3e050b1.tar.gz
kernel-qcow2-linux-df0db3ecdb8fc942e9d812558b8e15ecd3e050b1.tar.xz
kernel-qcow2-linux-df0db3ecdb8fc942e9d812558b8e15ecd3e050b1.zip
iomap: Add a page_prepare callback
Move the page_done callback into a separate iomap_page_ops structure and add a page_prepare calback to be called before the next page is written to. In gfs2, we'll want to start a transaction in page_prepare and end it in page_done. Other filesystems that implement data journaling will require the same kind of mechanism. Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Jan Kara <jack@suse.cz> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Diffstat (limited to 'fs/gfs2/bmap.c')
-rw-r--r--fs/gfs2/bmap.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
index 02b2646d84b3..f6d1a3893f5a 100644
--- a/fs/gfs2/bmap.c
+++ b/fs/gfs2/bmap.c
@@ -965,15 +965,20 @@ static void gfs2_write_unlock(struct inode *inode)
gfs2_glock_dq_uninit(&ip->i_gh);
}
-static void gfs2_iomap_journaled_page_done(struct inode *inode, loff_t pos,
- unsigned copied, struct page *page,
- struct iomap *iomap)
+static void gfs2_iomap_page_done(struct inode *inode, loff_t pos,
+ unsigned copied, struct page *page,
+ struct iomap *iomap)
{
struct gfs2_inode *ip = GFS2_I(inode);
- gfs2_page_add_databufs(ip, page, offset_in_page(pos), copied);
+ if (page)
+ gfs2_page_add_databufs(ip, page, offset_in_page(pos), copied);
}
+static const struct iomap_page_ops gfs2_iomap_page_ops = {
+ .page_done = gfs2_iomap_page_done,
+};
+
static int gfs2_iomap_begin_write(struct inode *inode, loff_t pos,
loff_t length, unsigned flags,
struct iomap *iomap,
@@ -1051,7 +1056,7 @@ static int gfs2_iomap_begin_write(struct inode *inode, loff_t pos,
}
}
if (!gfs2_is_stuffed(ip) && gfs2_is_jdata(ip))
- iomap->page_done = gfs2_iomap_journaled_page_done;
+ iomap->page_ops = &gfs2_iomap_page_ops;
return 0;
out_trans_end: