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

 - Fix the code that cleans up left-over unlinked files.

   Various fixes and minor improvements in deleting files cached or held
   open remotely.

 - Simplify the use of dlm's DLM_LKF_QUECVT flag.

 - A few other minor cleanups.

* tag 'gfs2-for-6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2: (21 commits)
  gfs2: Prevent inode creation race
  gfs2: Only defer deletes when we have an iopen glock
  gfs2: Simplify DLM_LKF_QUECVT use
  gfs2: gfs2_evict_inode clarification
  gfs2: Make gfs2_inode_refresh static
  gfs2: Use get_random_u32 in gfs2_orlov_skip
  gfs2: Randomize GLF_VERIFY_DELETE work delay
  gfs2: Use mod_delayed_work in gfs2_queue_try_to_evict
  gfs2: Update to the evict / remote delete documentation
  gfs2: Call gfs2_queue_verify_delete from gfs2_evict_inode
  gfs2: Clean up delete work processing
  gfs2: Minor delete_work_func cleanup
  gfs2: Return enum evict_behavior from gfs2_upgrade_iopen_glock
  gfs2: Rename dinode_demise to evict_behavior
  gfs2: Rename GIF_{DEFERRED -> DEFER}_DELETE
  gfs2: Faster gfs2_upgrade_iopen_glock wakeups
  KMSAN: uninit-value in inode_go_dump (5)
  gfs2: Fix unlinked inode cleanup
  gfs2: Allow immediate GLF_VERIFY_DELETE work
  gfs2: Initialize gl_no_formal_ino earlier
  ...
parents 7eef7e30 ffd1cf04
Loading
Loading
Loading
Loading
+41 −66
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@
#include <linux/rhashtable.h>
#include <linux/pid_namespace.h>
#include <linux/file.h>
#include <linux/random.h>

#include "gfs2.h"
#include "incore.h"
@@ -562,11 +563,11 @@ static void state_change(struct gfs2_glock *gl, unsigned int new_state)
	gl->gl_tchange = jiffies;
}

static void gfs2_set_demote(struct gfs2_glock *gl)
static void gfs2_set_demote(int nr, struct gfs2_glock *gl)
{
	struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;

	set_bit(GLF_DEMOTE, &gl->gl_flags);
	set_bit(nr, &gl->gl_flags);
	smp_mb();
	wake_up(&sdp->sd_async_glock_wait);
}
@@ -958,20 +959,22 @@ static void gfs2_glock_poke(struct gfs2_glock *gl)
	gfs2_holder_uninit(&gh);
}

static bool gfs2_try_evict(struct gfs2_glock *gl)
static void gfs2_try_evict(struct gfs2_glock *gl)
{
	struct gfs2_inode *ip;
	bool evicted = false;

	/*
	 * If there is contention on the iopen glock and we have an inode, try
	 * to grab and release the inode so that it can be evicted.  This will
	 * allow the remote node to go ahead and delete the inode without us
	 * having to do it, which will avoid rgrp glock thrashing.
	 * to grab and release the inode so that it can be evicted.  The
	 * GIF_DEFER_DELETE flag indicates to gfs2_evict_inode() that the inode
	 * should not be deleted locally.  This will allow the remote node to
	 * go ahead and delete the inode without us having to do it, which will
	 * avoid rgrp glock thrashing.
	 *
	 * The remote node is likely still holding the corresponding inode
	 * glock, so it will run before we get to verify that the delete has
	 * happened below.
	 * happened below.  (Verification is triggered by the call to
	 * gfs2_queue_verify_delete() in gfs2_evict_inode().)
	 */
	spin_lock(&gl->gl_lockref.lock);
	ip = gl->gl_object;
@@ -979,8 +982,14 @@ static bool gfs2_try_evict(struct gfs2_glock *gl)
		ip = NULL;
	spin_unlock(&gl->gl_lockref.lock);
	if (ip) {
		gl->gl_no_formal_ino = ip->i_no_formal_ino;
		set_bit(GIF_DEFERRED_DELETE, &ip->i_flags);
		wait_on_inode(&ip->i_inode);
		if (is_bad_inode(&ip->i_inode)) {
			iput(&ip->i_inode);
			ip = NULL;
		}
	}
	if (ip) {
		set_bit(GIF_DEFER_DELETE, &ip->i_flags);
		d_prune_aliases(&ip->i_inode);
		iput(&ip->i_inode);

@@ -988,7 +997,7 @@ static bool gfs2_try_evict(struct gfs2_glock *gl)
		spin_lock(&gl->gl_lockref.lock);
		ip = gl->gl_object;
		if (ip) {
			clear_bit(GIF_DEFERRED_DELETE, &ip->i_flags);
			clear_bit(GIF_DEFER_DELETE, &ip->i_flags);
			if (!igrab(&ip->i_inode))
				ip = NULL;
		}
@@ -997,9 +1006,7 @@ static bool gfs2_try_evict(struct gfs2_glock *gl)
			gfs2_glock_poke(ip->i_gl);
			iput(&ip->i_inode);
		}
		evicted = !ip;
	}
	return evicted;
}

bool gfs2_queue_try_to_evict(struct gfs2_glock *gl)
@@ -1008,18 +1015,18 @@ bool gfs2_queue_try_to_evict(struct gfs2_glock *gl)

	if (test_and_set_bit(GLF_TRY_TO_EVICT, &gl->gl_flags))
		return false;
	return queue_delayed_work(sdp->sd_delete_wq,
				  &gl->gl_delete, 0);
	return !mod_delayed_work(sdp->sd_delete_wq, &gl->gl_delete, 0);
}

static bool gfs2_queue_verify_evict(struct gfs2_glock *gl)
bool gfs2_queue_verify_delete(struct gfs2_glock *gl, bool later)
{
	struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
	unsigned long delay;

	if (test_and_set_bit(GLF_VERIFY_EVICT, &gl->gl_flags))
	if (test_and_set_bit(GLF_VERIFY_DELETE, &gl->gl_flags))
		return false;
	return queue_delayed_work(sdp->sd_delete_wq,
				  &gl->gl_delete, 5 * HZ);
	delay = later ? HZ + get_random_long() % (HZ * 9) : 0;
	return queue_delayed_work(sdp->sd_delete_wq, &gl->gl_delete, delay);
}

static void delete_work_func(struct work_struct *work)
@@ -1027,43 +1034,21 @@ static void delete_work_func(struct work_struct *work)
	struct delayed_work *dwork = to_delayed_work(work);
	struct gfs2_glock *gl = container_of(dwork, struct gfs2_glock, gl_delete);
	struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
	struct inode *inode;
	u64 no_addr = gl->gl_name.ln_number;
	bool verify_delete = test_and_clear_bit(GLF_VERIFY_DELETE, &gl->gl_flags);

	if (test_and_clear_bit(GLF_TRY_TO_EVICT, &gl->gl_flags)) {
		/*
		 * If we can evict the inode, give the remote node trying to
		 * delete the inode some time before verifying that the delete
		 * has happened.  Otherwise, if we cause contention on the inode glock
		 * immediately, the remote node will think that we still have
		 * the inode in use, and so it will give up waiting.
		 *
		 * If we can't evict the inode, signal to the remote node that
		 * the inode is still in use.  We'll later try to delete the
		 * inode locally in gfs2_evict_inode.
		 *
		 * FIXME: We only need to verify that the remote node has
		 * deleted the inode because nodes before this remote delete
		 * rework won't cooperate.  At a later time, when we no longer
		 * care about compatibility with such nodes, we can skip this
		 * step entirely.
		 */
		if (gfs2_try_evict(gl)) {
			if (test_bit(SDF_KILL, &sdp->sd_flags))
				goto out;
			if (gfs2_queue_verify_evict(gl))
				return;
		}
		goto out;
	}
	if (test_and_clear_bit(GLF_TRY_TO_EVICT, &gl->gl_flags))
		gfs2_try_evict(gl);

	if (verify_delete) {
		u64 no_addr = gl->gl_name.ln_number;
		struct inode *inode;

	if (test_and_clear_bit(GLF_VERIFY_EVICT, &gl->gl_flags)) {
		inode = gfs2_lookup_by_inum(sdp, no_addr, gl->gl_no_formal_ino,
					    GFS2_BLKST_UNLINKED);
		if (IS_ERR(inode)) {
			if (PTR_ERR(inode) == -EAGAIN &&
			    !test_bit(SDF_KILL, &sdp->sd_flags) &&
			    gfs2_queue_verify_evict(gl))
			    gfs2_queue_verify_delete(gl, true))
				return;
		} else {
			d_prune_aliases(inode);
@@ -1071,7 +1056,6 @@ static void delete_work_func(struct work_struct *work)
		}
	}

out:
	gfs2_glock_put(gl);
}

@@ -1100,7 +1084,7 @@ static void glock_work_func(struct work_struct *work)

		if (!delay) {
			clear_bit(GLF_PENDING_DEMOTE, &gl->gl_flags);
			gfs2_set_demote(gl);
			gfs2_set_demote(GLF_DEMOTE, gl);
		}
	}
	run_queue(gl, 0);
@@ -1442,10 +1426,7 @@ int gfs2_glock_async_wait(unsigned int num_gh, struct gfs2_holder *ghs)
static void request_demote(struct gfs2_glock *gl, unsigned int state,
			   unsigned long delay, bool remote)
{
	if (delay)
		set_bit(GLF_PENDING_DEMOTE, &gl->gl_flags);
	else
		gfs2_set_demote(gl);
	gfs2_set_demote(delay ? GLF_PENDING_DEMOTE : GLF_DEMOTE, gl);
	if (gl->gl_demote_state == LM_ST_EXCLUSIVE) {
		gl->gl_demote_state = state;
		gl->gl_demote_time = jiffies;
@@ -1635,12 +1616,6 @@ int gfs2_glock_poll(struct gfs2_holder *gh)
	return test_bit(HIF_WAIT, &gh->gh_iflags) ? 0 : 1;
}

static inline bool needs_demote(struct gfs2_glock *gl)
{
	return (test_bit(GLF_DEMOTE, &gl->gl_flags) ||
		test_bit(GLF_PENDING_DEMOTE, &gl->gl_flags));
}

static void __gfs2_glock_dq(struct gfs2_holder *gh)
{
	struct gfs2_glock *gl = gh->gh_gl;
@@ -1649,8 +1624,8 @@ static void __gfs2_glock_dq(struct gfs2_holder *gh)

	/*
	 * This holder should not be cached, so mark it for demote.
	 * Note: this should be done before the check for needs_demote
	 * below.
	 * Note: this should be done before the glock_needs_demote
	 * check below.
	 */
	if (gh->gh_flags & GL_NOCACHE)
		request_demote(gl, LM_ST_UNLOCKED, 0, false);
@@ -1663,7 +1638,7 @@ static void __gfs2_glock_dq(struct gfs2_holder *gh)
	 * If there hasn't been a demote request we are done.
	 * (Let the remaining holders, if any, keep holding it.)
	 */
	if (!needs_demote(gl)) {
	if (!glock_needs_demote(gl)) {
		if (list_empty(&gl->gl_holders))
			fast_path = 1;
	}
@@ -2117,7 +2092,7 @@ static void glock_hash_walk(glock_examiner examiner, const struct gfs2_sbd *sdp)
void gfs2_cancel_delete_work(struct gfs2_glock *gl)
{
	clear_bit(GLF_TRY_TO_EVICT, &gl->gl_flags);
	clear_bit(GLF_VERIFY_EVICT, &gl->gl_flags);
	clear_bit(GLF_VERIFY_DELETE, &gl->gl_flags);
	if (cancel_delayed_work(&gl->gl_delete))
		gfs2_glock_put(gl);
}
@@ -2370,7 +2345,7 @@ static const char *gflags2str(char *buf, const struct gfs2_glock *gl)
		*p++ = 'N';
	if (test_bit(GLF_TRY_TO_EVICT, gflags))
		*p++ = 'e';
	if (test_bit(GLF_VERIFY_EVICT, gflags))
	if (test_bit(GLF_VERIFY_DELETE, gflags))
		*p++ = 'E';
	*p = 0;
	return buf;
+7 −0
Original line number Diff line number Diff line
@@ -245,6 +245,7 @@ static inline int gfs2_glock_nq_init(struct gfs2_glock *gl,
void gfs2_glock_cb(struct gfs2_glock *gl, unsigned int state);
void gfs2_glock_complete(struct gfs2_glock *gl, int ret);
bool gfs2_queue_try_to_evict(struct gfs2_glock *gl);
bool gfs2_queue_verify_delete(struct gfs2_glock *gl, bool later);
void gfs2_cancel_delete_work(struct gfs2_glock *gl);
void gfs2_flush_delete_work(struct gfs2_sbd *sdp);
void gfs2_gl_hash_clear(struct gfs2_sbd *sdp);
@@ -284,4 +285,10 @@ static inline bool gfs2_holder_queued(struct gfs2_holder *gh)
void gfs2_inode_remember_delete(struct gfs2_glock *gl, u64 generation);
bool gfs2_inode_already_deleted(struct gfs2_glock *gl, u64 generation);

static inline bool glock_needs_demote(struct gfs2_glock *gl)
{
	return (test_bit(GLF_DEMOTE, &gl->gl_flags) ||
		test_bit(GLF_PENDING_DEMOTE, &gl->gl_flags));
}

#endif /* __GLOCK_DOT_H__ */
+9 −2
Original line number Diff line number Diff line
@@ -470,7 +470,7 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)
 * Returns: errno
 */

int gfs2_inode_refresh(struct gfs2_inode *ip)
static int gfs2_inode_refresh(struct gfs2_inode *ip)
{
	struct buffer_head *dibh;
	int error;
@@ -494,11 +494,18 @@ int gfs2_inode_refresh(struct gfs2_inode *ip)
static int inode_go_instantiate(struct gfs2_glock *gl)
{
	struct gfs2_inode *ip = gl->gl_object;
	struct gfs2_glock *io_gl;
	int error;

	if (!ip) /* no inode to populate - read it in later */
		return 0;

	return gfs2_inode_refresh(ip);
	error = gfs2_inode_refresh(ip);
	if (error)
		return error;
	io_gl = ip->i_iopen_gh.gh_gl;
	io_gl->gl_no_formal_ino = ip->i_no_formal_ino;
	return 0;
}

static int inode_go_held(struct gfs2_holder *gh)
+2 −2
Original line number Diff line number Diff line
@@ -329,7 +329,7 @@ enum {
	GLF_BLOCKING			= 15,
	GLF_UNLOCKED			= 16, /* Wait for glock to be unlocked */
	GLF_TRY_TO_EVICT		= 17, /* iopen glocks only */
	GLF_VERIFY_EVICT		= 18, /* iopen glocks only */
	GLF_VERIFY_DELETE		= 18, /* iopen glocks only */
};

struct gfs2_glock {
@@ -376,7 +376,7 @@ enum {
	GIF_SW_PAGED		= 3,
	GIF_FREE_VFS_INODE      = 5,
	GIF_GLOP_PENDING	= 6,
	GIF_DEFERRED_DELETE	= 7,
	GIF_DEFER_DELETE	= 7,
};

struct gfs2_inode {
+1 −0
Original line number Diff line number Diff line
@@ -750,6 +750,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
	if (error)
		goto fail_free_inode;
	gfs2_cancel_delete_work(io_gl);
	io_gl->gl_no_formal_ino = ip->i_no_formal_ino;

retry:
	error = insert_inode_locked4(inode, ip->i_no_addr, iget_test, &ip->i_no_addr);
Loading