Commit 3d3a9c8b authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull dlm updates from David Teigland:

 - Fix a case where the new scanning code missed removing an unused rsb

 - Fix the error when removing a configfs entry for an invalid node id

* tag 'dlm-6.14' of git://git.kernel.org/pub/scm/linux/kernel/git/teigland/linux-dlm:
  dlm: return -ENOENT if no comm was found
  dlm: fix srcu_read_lock() return type to int
  dlm: fix removal of rsb struct that is master and dir record
parents 2622f290 6784ed98
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -935,7 +935,7 @@ int dlm_comm_seq(int nodeid, uint32_t *seq, bool locked)
		mutex_unlock(&clusters_root.subsys.su_mutex);
	}
	if (!cm)
		return -EEXIST;
		return -ENOENT;

	*seq = cm->seq;
	put_comm(cm);
+30 −16
Original line number Diff line number Diff line
@@ -824,8 +824,11 @@ static int find_rsb_dir(struct dlm_ls *ls, const void *name, int len,
		r->res_first_lkid = 0;
	}

	/* A dir record will not be on the scan list. */
	if (r->res_dir_nodeid != our_nodeid)
	/* we always deactivate scan timer for the rsb, when
	 * we move it out of the inactive state as rsb state
	 * can be changed and scan timers are only for inactive
	 * rsbs.
	 */
	del_scan(ls, r);
	list_move(&r->res_slow_list, &ls->ls_slow_active);
	rsb_clear_flag(r, RSB_INACTIVE);
@@ -989,10 +992,10 @@ static int find_rsb_nodir(struct dlm_ls *ls, const void *name, int len,
		r->res_nodeid = 0;
	}

	del_scan(ls, r);
	list_move(&r->res_slow_list, &ls->ls_slow_active);
	rsb_clear_flag(r, RSB_INACTIVE);
	kref_init(&r->res_ref);
	del_scan(ls, r);
	write_unlock_bh(&ls->ls_rsbtbl_lock);

	goto out;
@@ -1337,9 +1340,13 @@ static int _dlm_master_lookup(struct dlm_ls *ls, int from_nodeid, const char *na
	__dlm_master_lookup(ls, r, our_nodeid, from_nodeid, true, flags,
			    r_nodeid, result);

	/* A dir record rsb should never be on scan list. */
	/* Try to fix this with del_scan? */
	WARN_ON(!list_empty(&r->res_scan_list));
	/* A dir record rsb should never be on scan list.
	 * Except when we are the dir and master node.
	 * This function should only be called by the dir
	 * node.
	 */
	WARN_ON(!list_empty(&r->res_scan_list) &&
		r->res_master_nodeid != our_nodeid);

	write_unlock_bh(&ls->ls_rsbtbl_lock);

@@ -1430,16 +1437,23 @@ static void deactivate_rsb(struct kref *kref)
	list_move(&r->res_slow_list, &ls->ls_slow_inactive);

	/*
	 * When the rsb becomes unused:
	 * - If it's not a dir record for a remote master rsb,
	 *   then it is put on the scan list to be freed.
	 * - If it's a dir record for a remote master rsb,
	 *   then it is kept in the inactive state until
	 *   receive_remove() from the master node.
	 * When the rsb becomes unused, there are two possibilities:
	 * 1. Leave the inactive rsb in place (don't remove it).
	 * 2. Add it to the scan list to be removed.
	 *
	 * 1 is done when the rsb is acting as the dir record
	 * for a remotely mastered rsb.  The rsb must be left
	 * in place as an inactive rsb to act as the dir record.
	 *
	 * 2 is done when a) the rsb is not the master and not the
	 * dir record, b) when the rsb is both the master and the
	 * dir record, c) when the rsb is master but not dir record.
	 *
	 * (If no directory is used, the rsb can always be removed.)
	 */
	if (!dlm_no_directory(ls) &&
	    (r->res_master_nodeid != our_nodeid) &&
	    (dlm_dir_nodeid(r) != our_nodeid))
	if (dlm_no_directory(ls) ||
	    (r->res_master_nodeid == our_nodeid ||
	     dlm_dir_nodeid(r) != our_nodeid))
		add_scan(ls, r);

	if (r->res_lvbptr) {
+2 −1
Original line number Diff line number Diff line
@@ -462,7 +462,8 @@ static bool dlm_lowcomms_con_has_addr(const struct connection *con,
int dlm_lowcomms_addr(int nodeid, struct sockaddr_storage *addr)
{
	struct connection *con;
	bool ret, idx;
	bool ret;
	int idx;

	idx = srcu_read_lock(&connections_srcu);
	con = nodeid2con(nodeid, GFP_NOFS);