Linux-Next discussions
 help / color / mirror / Atom feed
* linux-next: manual merge of the vfs-brauner tree with the gfs2 tree
@ 2026-07-29 12:30 Mark Brown
  0 siblings, 0 replies; only message in thread
From: Mark Brown @ 2026-07-29 12:30 UTC (permalink / raw)
  To: Christian Brauner
  Cc: Andreas Gruenbacher, Linux Kernel Mailing List,
	Linux Next Mailing List, Mateusz Guzik

[-- Attachment #1: Type: text/plain, Size: 12234 bytes --]

Hi all,

Today's linux-next merge of the vfs-brauner tree got a conflict in:

  fs/gfs2/glock.c

between commit:

  da26828b82a45 ("gfs2: Remove the glock lru list and shrinker")

from the gfs2 tree and commit:

  21a8e80682781 ("lockref: tidy up dead count handling")

from the vfs-brauner tree.

I fixed it up (see below) and can carry the fix as necessary. This
is now fixed as far as linux-next is concerned, but any non trivial
conflicts should be mentioned to your upstream maintainer when your tree
is submitted for merging.  You may also want to consider cooperating
with the maintainer of the conflicting tree to minimise any particularly
complex conflicts.

diff --combined fs/gfs2/glock.c
index 558c8c660a3d4,eaa2980051ed5..0000000000000
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@@ -66,6 -66,9 +66,6 @@@ static void request_demote(struct gfs2_
  			   unsigned long delay, bool remote);
  
  static struct dentry *gfs2_root;
 -static LIST_HEAD(lru_list);
 -static atomic_t lru_count = ATOMIC_INIT(0);
 -static DEFINE_SPINLOCK(lru_lock);
  
  #define GFS2_GL_HASH_SHIFT      15
  #define GFS2_GL_HASH_SIZE       BIT(GFS2_GL_HASH_SHIFT)
@@@ -75,7 -78,6 +75,7 @@@ static const struct rhashtable_params h
  	.key_len = offsetofend(struct lm_lockname, ln_type),
  	.key_offset = offsetof(struct gfs2_glock, gl_name),
  	.head_offset = offsetof(struct gfs2_glock, gl_node),
 +	.automatic_shrinking = true,
  };
  
  static struct rhashtable gl_hash_table;
@@@ -155,9 -157,9 +155,9 @@@ void gfs2_glock_free(struct gfs2_glock 
  void gfs2_glock_free_later(struct gfs2_glock *gl) {
  	struct gfs2_sbd *sdp = glock_sbd(gl);
  
 -	spin_lock(&lru_lock);
 -	list_add(&gl->gl_lru, &sdp->sd_dead_glocks);
 -	spin_unlock(&lru_lock);
 +	spin_lock(&sdp->sd_dead_lock);
 +	list_add(&gl->gl_dead, &sdp->sd_dead_glocks);
 +	spin_unlock(&sdp->sd_dead_lock);
  	if (atomic_dec_and_test(&sdp->sd_glock_disposal))
  		wake_up(&sdp->sd_kill_wait);
  }
@@@ -169,8 -171,8 +169,8 @@@ static void gfs2_free_dead_glocks(struc
  	while(!list_empty(list)) {
  		struct gfs2_glock *gl;
  
 -		gl = list_first_entry(list, struct gfs2_glock, gl_lru);
 -		list_del_init(&gl->gl_lru);
 +		gl = list_first_entry(list, struct gfs2_glock, gl_dead);
 +		list_del(&gl->gl_dead);
  		__gfs2_glock_free(gl);
  	}
  }
@@@ -188,6 -190,30 +188,6 @@@ struct gfs2_glock *gfs2_glock_hold(stru
  	return gl;
  }
  
 -static void gfs2_glock_add_to_lru(struct gfs2_glock *gl)
 -{
 -	spin_lock(&lru_lock);
 -	list_move_tail(&gl->gl_lru, &lru_list);
 -
 -	if (!test_bit(GLF_LRU, &gl->gl_flags)) {
 -		set_bit(GLF_LRU, &gl->gl_flags);
 -		atomic_inc(&lru_count);
 -	}
 -
 -	spin_unlock(&lru_lock);
 -}
 -
 -static void gfs2_glock_remove_from_lru(struct gfs2_glock *gl)
 -{
 -	spin_lock(&lru_lock);
 -	if (test_bit(GLF_LRU, &gl->gl_flags)) {
 -		list_del_init(&gl->gl_lru);
 -		atomic_dec(&lru_count);
 -		clear_bit(GLF_LRU, &gl->gl_flags);
 -	}
 -	spin_unlock(&lru_lock);
 -}
 -
  /*
   * Enqueue the glock on the work queue.  Passes one glock reference on to the
   * work queue.
@@@ -214,6 -240,7 +214,6 @@@ static void __gfs2_glock_put(struct gfs
  
  	lockref_mark_dead(&gl->gl_lockref);
  	spin_unlock(&gl->gl_lockref.lock);
 -	gfs2_glock_remove_from_lru(gl);
  	GLOCK_BUG_ON(gl, !list_empty(&gl->gl_holders));
  	if (mapping) {
  		truncate_inode_pages_final(mapping);
@@@ -230,8 -257,8 +230,8 @@@ static bool __gfs2_glock_put_or_lock(st
  		return true;
  	GLOCK_BUG_ON(gl, gl->gl_lockref.count != 1);
  	if (gl->gl_state != LM_ST_UNLOCKED) {
 -		gl->gl_lockref.count--;
 -		gfs2_glock_add_to_lru(gl);
 +		request_demote(gl, LM_ST_UNLOCKED, 0, false);
 +		gfs2_glock_queue_work(gl, 0);
  		spin_unlock(&gl->gl_lockref.lock);
  		return true;
  	}
@@@ -955,19 -982,16 +955,19 @@@ static void delete_work_func(struct wor
  
  static void glock_work_func(struct work_struct *work)
  {
 -	unsigned long delay = 0;
  	struct gfs2_glock *gl = container_of(work, struct gfs2_glock, gl_work.work);
 -	unsigned int drop_refs = 1;
 +	unsigned int drop_refs;
 +	unsigned long delay;
  
  	spin_lock(&gl->gl_lockref.lock);
 +again:
 +	drop_refs = 1;
  	if (test_bit(GLF_HAVE_REPLY, &gl->gl_flags)) {
  		clear_bit(GLF_HAVE_REPLY, &gl->gl_flags);
  		finish_xmote(gl, gl->gl_reply);
  		drop_refs++;
  	}
 +	delay = 0;
  	if (test_bit(GLF_PENDING_DEMOTE, &gl->gl_flags) &&
  	    gl->gl_state != LM_ST_UNLOCKED &&
  	    gl->gl_demote_state != LM_ST_EXCLUSIVE) {
@@@ -995,13 -1019,11 +995,13 @@@
  	GLOCK_BUG_ON(gl, gl->gl_lockref.count < drop_refs);
  	gl->gl_lockref.count -= drop_refs;
  	if (!gl->gl_lockref.count) {
 -		if (gl->gl_state == LM_ST_UNLOCKED) {
 -			__gfs2_glock_put(gl);
 -			return;
 +		if (gl->gl_state != LM_ST_UNLOCKED) {
 +			gl->gl_lockref.count++;
 +			request_demote(gl, LM_ST_UNLOCKED, 0, false);
 +			goto again;
  		}
 -		gfs2_glock_add_to_lru(gl);
 +		__gfs2_glock_put(gl);
 +		return;
  	}
  	spin_unlock(&gl->gl_lockref.lock);
  }
@@@ -1037,6 -1059,8 +1037,6 @@@ again
  out:
  	rcu_read_unlock();
  	finish_wait(wq, &wait.wait);
 -	if (gl)
 -		gfs2_glock_remove_from_lru(gl);
  	return gl;
  }
  
@@@ -1849,6 -1873,125 +1849,6 @@@ void gfs2_glock_complete(struct gfs2_gl
  	spin_unlock(&gl->gl_lockref.lock);
  }
  
 -static int glock_cmp(void *priv, const struct list_head *a,
 -		     const struct list_head *b)
 -{
 -	struct gfs2_glock *gla, *glb;
 -
 -	gla = list_entry(a, struct gfs2_glock, gl_lru);
 -	glb = list_entry(b, struct gfs2_glock, gl_lru);
 -
 -	if (glock_number(gla) > glock_number(glb))
 -		return 1;
 -	if (glock_number(gla) < glock_number(glb))
 -		return -1;
 -
 -	return 0;
 -}
 -
 -static bool can_free_glock(struct gfs2_glock *gl)
 -{
 -	struct gfs2_sbd *sdp = glock_sbd(gl);
 -
 -	return !test_bit(GLF_LOCK, &gl->gl_flags) &&
 -	       !gl->gl_lockref.count &&
 -	       (!test_bit(GLF_LFLUSH, &gl->gl_flags) ||
 -		test_bit(SDF_KILL, &sdp->sd_flags));
 -}
 -
 -/**
 - * gfs2_dispose_glock_lru - Demote a list of glocks
 - * @list: The list to dispose of
 - *
 - * Disposing of glocks may involve disk accesses, so that here we sort
 - * the glocks by number (i.e. disk location of the inodes) so that if
 - * there are any such accesses, they'll be sent in order (mostly).
 - *
 - * Must be called under the lru_lock, but may drop and retake this
 - * lock. While the lru_lock is dropped, entries may vanish from the
 - * list, but no new entries will appear on the list (since it is
 - * private)
 - */
 -
 -static unsigned long gfs2_dispose_glock_lru(struct list_head *list)
 -__releases(&lru_lock)
 -__acquires(&lru_lock)
 -{
 -	struct gfs2_glock *gl;
 -	unsigned long freed = 0;
 -
 -	list_sort(NULL, list, glock_cmp);
 -
 -	while(!list_empty(list)) {
 -		gl = list_first_entry(list, struct gfs2_glock, gl_lru);
 -		if (!spin_trylock(&gl->gl_lockref.lock)) {
 -add_back_to_lru:
 -			list_move(&gl->gl_lru, &lru_list);
 -			continue;
 -		}
 -		if (!can_free_glock(gl)) {
 -			spin_unlock(&gl->gl_lockref.lock);
 -			goto add_back_to_lru;
 -		}
 -		list_del_init(&gl->gl_lru);
 -		atomic_dec(&lru_count);
 -		clear_bit(GLF_LRU, &gl->gl_flags);
 -		freed++;
 -		gl->gl_lockref.count++;
 -		if (gl->gl_state != LM_ST_UNLOCKED)
 -			request_demote(gl, LM_ST_UNLOCKED, 0, false);
 -		gfs2_glock_queue_work(gl, 0);
 -		spin_unlock(&gl->gl_lockref.lock);
 -		cond_resched_lock(&lru_lock);
 -	}
 -	return freed;
 -}
 -
 -/**
 - * gfs2_scan_glock_lru - Scan the LRU looking for locks to demote
 - * @nr: The number of entries to scan
 - *
 - * This function selects the entries on the LRU which are able to
 - * be demoted, and then kicks off the process by calling
 - * gfs2_dispose_glock_lru() above.
 - */
 -
 -static unsigned long gfs2_scan_glock_lru(unsigned long nr)
 -{
 -	struct gfs2_glock *gl, *next;
 -	LIST_HEAD(dispose);
 -	unsigned long freed = 0;
 -
 -	spin_lock(&lru_lock);
 -	list_for_each_entry_safe(gl, next, &lru_list, gl_lru) {
 -		if (!nr--)
 -			break;
 -		if (can_free_glock(gl))
 -			list_move(&gl->gl_lru, &dispose);
 -	}
 -	if (!list_empty(&dispose))
 -		freed = gfs2_dispose_glock_lru(&dispose);
 -	spin_unlock(&lru_lock);
 -
 -	return freed;
 -}
 -
 -static unsigned long gfs2_glock_shrink_scan(struct shrinker *shrink,
 -					    struct shrink_control *sc)
 -{
 -	if (!(sc->gfp_mask & __GFP_FS))
 -		return SHRINK_STOP;
 -	return gfs2_scan_glock_lru(sc->nr_to_scan);
 -}
 -
 -static unsigned long gfs2_glock_shrink_count(struct shrinker *shrink,
 -					     struct shrink_control *sc)
 -{
 -	return vfs_pressure_ratio(atomic_read(&lru_count));
 -}
 -
 -static struct shrinker *glock_shrinker;
 -
  /**
   * glock_hash_walk - Call a function for glock in a hash bucket
   * @examiner: the function
@@@ -1919,12 -2062,33 +1919,12 @@@ static void thaw_glock(struct gfs2_gloc
  	if (!lockref_get_not_dead(&gl->gl_lockref))
  		return;
  
 -	gfs2_glock_remove_from_lru(gl);
  	spin_lock(&gl->gl_lockref.lock);
  	set_bit(GLF_HAVE_REPLY, &gl->gl_flags);
  	gfs2_glock_queue_work(gl, 0);
  	spin_unlock(&gl->gl_lockref.lock);
  }
  
 -/**
 - * clear_glock - look at a glock and see if we can free it from glock cache
 - * @gl: the glock to look at
 - *
 - */
 -
 -static void clear_glock(struct gfs2_glock *gl)
 -{
 -	gfs2_glock_remove_from_lru(gl);
 -
 -	spin_lock(&gl->gl_lockref.lock);
 -	if (!lockref_is_dead(&gl->gl_lockref)) {
 -		gl->gl_lockref.count++;
 -		if (gl->gl_state != LM_ST_UNLOCKED)
 -			request_demote(gl, LM_ST_UNLOCKED, 0, false);
 -		gfs2_glock_queue_work(gl, 0);
 -	}
 -	spin_unlock(&gl->gl_lockref.lock);
 -}
 -
  /**
   * gfs2_glock_thaw - Thaw any frozen glocks
   * @sdp: The super block
@@@ -1951,7 -2115,7 +1951,7 @@@ static void dump_glock_func(struct gfs2
  static void withdraw_glock(struct gfs2_glock *gl)
  {
  	spin_lock(&gl->gl_lockref.lock);
- 	if (!__lockref_is_dead(&gl->gl_lockref)) {
+ 	if (!lockref_is_dead(&gl->gl_lockref)) {
  		/*
  		 * We don't want to write back any more dirty data.  Unlock the
  		 * remaining inode and resource group glocks; this will cause
@@@ -1971,17 -2135,22 +1971,17 @@@ void gfs2_withdraw_glocks(struct gfs2_s
  }
  
  /**
 - * gfs2_gl_hash_clear - Empty out the glock hash table
 + * gfs2_wait_glocks - Wait for the remaining glocks to go away
   * @sdp: the filesystem
   *
   * Called when unmounting the filesystem.
   */
  
 -void gfs2_gl_hash_clear(struct gfs2_sbd *sdp)
 +void gfs2_wait_glocks(struct gfs2_sbd *sdp)
  {
  	unsigned long start = jiffies;
  	bool timed_out = false;
  
 -	set_bit(SDF_SKIP_DLM_UNLOCK, &sdp->sd_flags);
 -	flush_workqueue(sdp->sd_glock_wq);
 -	glock_hash_walk(clear_glock, sdp);
 -	flush_workqueue(sdp->sd_glock_wq);
 -
  	while (!timed_out) {
  		wait_event_timeout(sdp->sd_kill_wait,
  				   !atomic_read(&sdp->sd_glock_disposal),
@@@ -2104,6 -2273,8 +2104,6 @@@ static const char *gflags2str(char *buf
  		*p++ = 'F';
  	if (!list_empty(&gl->gl_holders))
  		*p++ = 'q';
 -	if (test_bit(GLF_LRU, gflags))
 -		*p++ = 'L';
  	if (gl->gl_object)
  		*p++ = 'o';
  	if (test_bit(GLF_BLOCKING, gflags))
@@@ -2263,6 -2434,17 +2263,6 @@@ int __init gfs2_glock_init(void
  	if (ret < 0)
  		return ret;
  
 -	glock_shrinker = shrinker_alloc(0, "gfs2-glock");
 -	if (!glock_shrinker) {
 -		rhashtable_destroy(&gl_hash_table);
 -		return -ENOMEM;
 -	}
 -
 -	glock_shrinker->count_objects = gfs2_glock_shrink_count;
 -	glock_shrinker->scan_objects = gfs2_glock_shrink_scan;
 -
 -	shrinker_register(glock_shrinker);
 -
  	for (i = 0; i < GLOCK_WAIT_TABLE_SIZE; i++)
  		init_waitqueue_head(glock_wait_table + i);
  
@@@ -2271,6 -2453,7 +2271,6 @@@
  
  void gfs2_glock_exit(void)
  {
 -	shrinker_free(glock_shrinker);
  	rhashtable_destroy(&gl_hash_table);
  }
  
@@@ -2300,7 -2483,7 +2300,7 @@@ static void gfs2_glock_iter_next(struc
  				continue;
  			break;
  		} else {
- 			if (__lockref_is_dead(&gl->gl_lockref))
+ 			if (lockref_is_dead(&gl->gl_lockref))
  				continue;
  			n--;
  		}

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2026-07-29 12:30 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-29 12:30 linux-next: manual merge of the vfs-brauner tree with the gfs2 tree Mark Brown

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox