Commit ae9f3bd8 authored by Andreas Gruenbacher's avatar Andreas Gruenbacher
Browse files

gfs2: replace sd_aspace with sd_inode



Currently, sdp->sd_aspace and the per-inode metadata address spaces use
sb->s_bdev->bd_mapping->host as their ->host; folios in those address
spaces will thus appear to be on bdev rather than on gfs2 filesystems.
This is a problem because gfs2 doesn't support cgroup writeback
(SB_I_CGROUPWB), but bdev does.

Fix that by using a "dummy" gfs2 inode as ->host in those address
spaces.  When coming from a folio, folio->mapping->host->i_sb will then
be a gfs2 super block and the SB_I_CGROUPWB flag will not be set in
sb->s_iflags.

Based on a previous version from Bob Peterson from several years ago.
Thanks to Tetsuo Handa, Jan Kara, and Rafael Aquini for helping figure
this out.

Fixes: aaa2cacf ("writeback: add lockdep annotation to inode_to_wb()")
Signed-off-by: default avatarAndreas Gruenbacher <agruenba@redhat.com>
parent ff22e5da
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -1166,7 +1166,6 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
		   const struct gfs2_glock_operations *glops, int create,
		   struct gfs2_glock **glp)
{
	struct super_block *s = sdp->sd_vfs;
	struct lm_lockname name = { .ln_number = number,
				    .ln_type = glops->go_type,
				    .ln_sbd = sdp };
@@ -1229,7 +1228,7 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
	mapping = gfs2_glock2aspace(gl);
	if (mapping) {
                mapping->a_ops = &gfs2_meta_aops;
		mapping->host = s->s_bdev->bd_mapping->host;
		mapping->host = sdp->sd_inode;
		mapping->flags = 0;
		mapping_set_gfp_mask(mapping, GFP_NOFS);
		mapping->i_private_data = NULL;
+2 −2
Original line number Diff line number Diff line
@@ -168,7 +168,7 @@ void gfs2_ail_flush(struct gfs2_glock *gl, bool fsync)
static int gfs2_rgrp_metasync(struct gfs2_glock *gl)
{
	struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
	struct address_space *metamapping = &sdp->sd_aspace;
	struct address_space *metamapping = gfs2_aspace(sdp);
	struct gfs2_rgrpd *rgd = gfs2_glock2rgrp(gl);
	const unsigned bsize = sdp->sd_sb.sb_bsize;
	loff_t start = (rgd->rd_addr * bsize) & PAGE_MASK;
@@ -225,7 +225,7 @@ static int rgrp_go_sync(struct gfs2_glock *gl)
static void rgrp_go_inval(struct gfs2_glock *gl, int flags)
{
	struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
	struct address_space *mapping = &sdp->sd_aspace;
	struct address_space *mapping = gfs2_aspace(sdp);
	struct gfs2_rgrpd *rgd = gfs2_glock2rgrp(gl);
	const unsigned bsize = sdp->sd_sb.sb_bsize;
	loff_t start, end;
+8 −1
Original line number Diff line number Diff line
@@ -795,7 +795,7 @@ struct gfs2_sbd {

	/* Log stuff */

	struct address_space sd_aspace;
	struct inode *sd_inode;

	spinlock_t sd_log_lock;

@@ -851,6 +851,13 @@ struct gfs2_sbd {
	unsigned long sd_glock_dqs_held;
};

#define GFS2_BAD_INO 1

static inline struct address_space *gfs2_aspace(struct gfs2_sbd *sdp)
{
	return sdp->sd_inode->i_mapping;
}

static inline void gfs2_glstats_inc(struct gfs2_glock *gl, int which)
{
	gl->gl_stats.stats[which]++;
+1 −1
Original line number Diff line number Diff line
@@ -132,7 +132,7 @@ struct buffer_head *gfs2_getbuf(struct gfs2_glock *gl, u64 blkno, int create)
	unsigned int bufnum;

	if (mapping == NULL)
		mapping = &sdp->sd_aspace;
		mapping = gfs2_aspace(sdp);

	shift = PAGE_SHIFT - sdp->sd_sb.sb_bsize_shift;
	index = blkno >> shift;             /* convert block to page */
+1 −3
Original line number Diff line number Diff line
@@ -44,9 +44,7 @@ static inline struct gfs2_sbd *gfs2_mapping2sbd(struct address_space *mapping)
		struct gfs2_glock_aspace *gla =
			container_of(mapping, struct gfs2_glock_aspace, mapping);
		return gla->glock.gl_name.ln_sbd;
	} else if (mapping->a_ops == &gfs2_rgrp_aops)
		return container_of(mapping, struct gfs2_sbd, sd_aspace);
	else
	} else
		return inode->i_sb->s_fs_info;
}

Loading