Commit 7208c984 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull gfs2 updates from Andreas Gruenbacher:

 - Clean up the allocation of glocks that have an address space attached

 - Quota locking fix and quota iomap conversion

 - Fix the FITRIM error reporting

 - Some list iterator cleanups

* tag 'gfs2-v5.18-rc6-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2:
  gfs2: Convert function bh_get to use iomap
  gfs2: use i_lock spin_lock for inode qadata
  gfs2: Return more useful errors from gfs2_rgrp_send_discards()
  gfs2: Use container_of() for gfs2_glock(aspace)
  gfs2: Explain some direct I/O oddities
  gfs2: replace 'found' with dedicated list iterator variable
parents bd1b7c13 c360abbb
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -840,6 +840,7 @@ static ssize_t gfs2_file_direct_read(struct kiocb *iocb, struct iov_iter *to,
	pagefault_enable();
	if (ret <= 0 && ret != -EFAULT)
		goto out_unlock;
	/* No increment (+=) because iomap_dio_rw returns a cumulative value. */
	if (ret > 0)
		read = ret;

@@ -854,6 +855,7 @@ static ssize_t gfs2_file_direct_read(struct kiocb *iocb, struct iov_iter *to,
		gfs2_glock_dq(gh);
out_uninit:
	gfs2_holder_uninit(gh);
	/* User space doesn't expect partial success. */
	if (ret < 0)
		return ret;
	return read;
@@ -906,6 +908,7 @@ static ssize_t gfs2_file_direct_write(struct kiocb *iocb, struct iov_iter *from,
		if (ret != -EFAULT)
			goto out_unlock;
	}
	/* No increment (+=) because iomap_dio_rw returns a cumulative value. */
	if (ret > 0)
		written = ret;

@@ -920,6 +923,7 @@ static ssize_t gfs2_file_direct_write(struct kiocb *iocb, struct iov_iter *from,
		gfs2_glock_dq(gh);
out_uninit:
	gfs2_holder_uninit(gh);
	/* User space doesn't expect partial success. */
	if (ret < 0)
		return ret;
	return written;
+19 −16
Original line number Diff line number Diff line
@@ -127,9 +127,11 @@ static void gfs2_glock_dealloc(struct rcu_head *rcu)
	struct gfs2_glock *gl = container_of(rcu, struct gfs2_glock, gl_rcu);

	kfree(gl->gl_lksb.sb_lvbptr);
	if (gl->gl_ops->go_flags & GLOF_ASPACE)
		kmem_cache_free(gfs2_glock_aspace_cachep, gl);
	else
	if (gl->gl_ops->go_flags & GLOF_ASPACE) {
		struct gfs2_glock_aspace *gla =
			container_of(gl, struct gfs2_glock_aspace, glock);
		kmem_cache_free(gfs2_glock_aspace_cachep, gla);
	} else
		kmem_cache_free(gfs2_glock_cachep, gl);
}

@@ -1159,7 +1161,6 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
				    .ln_sbd = sdp };
	struct gfs2_glock *gl, *tmp;
	struct address_space *mapping;
	struct kmem_cache *cachep;
	int ret = 0;

	gl = find_insert_glock(&name, NULL);
@@ -1170,20 +1171,24 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
	if (!create)
		return -ENOENT;

	if (glops->go_flags & GLOF_ASPACE)
		cachep = gfs2_glock_aspace_cachep;
	else
		cachep = gfs2_glock_cachep;
	gl = kmem_cache_alloc(cachep, GFP_NOFS);
	if (glops->go_flags & GLOF_ASPACE) {
		struct gfs2_glock_aspace *gla =
			kmem_cache_alloc(gfs2_glock_aspace_cachep, GFP_NOFS);
		if (!gla)
			return -ENOMEM;
		gl = &gla->glock;
	} else {
		gl = kmem_cache_alloc(gfs2_glock_cachep, GFP_NOFS);
		if (!gl)
			return -ENOMEM;

	}
	memset(&gl->gl_lksb, 0, sizeof(struct dlm_lksb));
	gl->gl_ops = glops;

	if (glops->go_flags & GLOF_LVB) {
		gl->gl_lksb.sb_lvbptr = kzalloc(GDLM_LVB_SIZE, GFP_NOFS);
		if (!gl->gl_lksb.sb_lvbptr) {
			kmem_cache_free(cachep, gl);
			gfs2_glock_dealloc(&gl->gl_rcu);
			return -ENOMEM;
		}
	}
@@ -1197,7 +1202,6 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
	gl->gl_state = LM_ST_UNLOCKED;
	gl->gl_target = LM_ST_UNLOCKED;
	gl->gl_demote_state = LM_ST_EXCLUSIVE;
	gl->gl_ops = glops;
	gl->gl_dstamp = 0;
	preempt_disable();
	/* We use the global stats to estimate the initial per-glock stats */
@@ -1234,8 +1238,7 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
	*glp = tmp;

out_free:
	kfree(gl->gl_lksb.sb_lvbptr);
	kmem_cache_free(cachep, gl);
	gfs2_glock_dealloc(&gl->gl_rcu);
	if (atomic_dec_and_test(&sdp->sd_glock_disposal))
		wake_up(&sdp->sd_glock_wait);

+10 −2
Original line number Diff line number Diff line
@@ -138,6 +138,11 @@ struct lm_lockops {
	const match_table_t *lm_tokens;
};

struct gfs2_glock_aspace {
	struct gfs2_glock glock;
	struct address_space mapping;
};

extern struct workqueue_struct *gfs2_delete_workqueue;
static inline struct gfs2_holder *gfs2_glock_is_locked_by_me(struct gfs2_glock *gl)
{
@@ -179,8 +184,11 @@ static inline int gfs2_glock_is_held_shrd(struct gfs2_glock *gl)

static inline struct address_space *gfs2_glock2aspace(struct gfs2_glock *gl)
{
	if (gl->gl_ops->go_flags & GLOF_ASPACE)
		return (struct address_space *)(gl + 1);
	if (gl->gl_ops->go_flags & GLOF_ASPACE) {
		struct gfs2_glock_aspace *gla =
			container_of(gl, struct gfs2_glock_aspace, glock);
		return &gla->mapping;
	}
	return NULL;
}

+4 −6
Original line number Diff line number Diff line
@@ -62,11 +62,10 @@ static void gfs2_init_glock_once(void *foo)

static void gfs2_init_gl_aspace_once(void *foo)
{
	struct gfs2_glock *gl = foo;
	struct address_space *mapping = (struct address_space *)(gl + 1);
	struct gfs2_glock_aspace *gla = foo;

	gfs2_init_glock_once(gl);
	address_space_init_once(mapping);
	gfs2_init_glock_once(&gla->glock);
	address_space_init_once(&gla->mapping);
}

/**
@@ -104,8 +103,7 @@ static int __init init_gfs2_fs(void)
		goto fail_cachep1;

	gfs2_glock_aspace_cachep = kmem_cache_create("gfs2_glock(aspace)",
					sizeof(struct gfs2_glock) +
					sizeof(struct address_space),
					sizeof(struct gfs2_glock_aspace),
					0, 0, gfs2_init_gl_aspace_once);

	if (!gfs2_glock_aspace_cachep)
+5 −3
Original line number Diff line number Diff line
@@ -40,9 +40,11 @@ extern const struct address_space_operations gfs2_rgrp_aops;
static inline struct gfs2_sbd *gfs2_mapping2sbd(struct address_space *mapping)
{
	struct inode *inode = mapping->host;
	if (mapping->a_ops == &gfs2_meta_aops)
		return (((struct gfs2_glock *)mapping) - 1)->gl_name.ln_sbd;
	else if (mapping->a_ops == &gfs2_rgrp_aops)
	if (mapping->a_ops == &gfs2_meta_aops) {
		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
		return inode->i_sb->s_fs_info;
Loading