Commit 0a37714f authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull dlm updates from David Teigland:
 "The dlm posix lock handling (for gfs2) has three notable changes:

   - Local pids returned from GETLK are no longer negated. A previous
     patch negating remote pids mistakenly changed local pids also.

   - SETLKW operations can now be interrupted only when the process is
     killed, and not from other signals. General interruption was
     resulting in previously acquired locks being cleared, not just the
     in-progress lock. Handling this correctly will require extending a
     cancel capability to user space (a future feature.)

   - If multiple threads are requesting posix locks (with SETLKW), fix
     incorrect matching of results to the requests.

  The dlm networking has several minor cleanups, and one notable change:

   - Avoid delaying ack messages for too long (used for message
     reliability), resulting in a backlog of un-acked messages. These
     could previously be delayed as a result of either too many or too
     few other messages being sent. Now an upper and lower threshold is
     used to determine when an ack should be sent"

* tag 'dlm-6.5' of git://git.kernel.org/pub/scm/linux/kernel/git/teigland/linux-dlm:
  fs: dlm: remove filter local comms on close
  fs: dlm: add send ack threshold and append acks to msgs
  fs: dlm: handle sequence numbers as atomic
  fs: dlm: handle lkb wait count as atomic_t
  fs: dlm: filter ourself midcomms calls
  fs: dlm: warn about messages from left nodes
  fs: dlm: move dlm_purge_lkb_callbacks to user module
  fs: dlm: cleanup STOP_IO bitflag set when stop io
  fs: dlm: don't check othercon twice
  fs: dlm: unregister memory at the very last
  fs: dlm: fix missing pending to false
  fs: dlm: clear pending bit when queue was empty
  fs: dlm: revert check required context while close
  fs: dlm: fix mismatch of plock results from userspace
  fs: dlm: make F_SETLK use unkillable wait_event
  fs: dlm: interrupt posix locks only when process is killed
  fs: dlm: fix cleanup pending ops when interrupted
  fs: dlm: return positive pid value for F_GETLK
  dlm: Replace all non-returning strlcpy with strscpy
parents 9e06150d fc4ea422
Loading
Loading
Loading
Loading
+5 −20
Original line number Diff line number Diff line
@@ -36,23 +36,6 @@ void dlm_callback_set_last_ptr(struct dlm_callback **from,
	*from = to;
}

void dlm_purge_lkb_callbacks(struct dlm_lkb *lkb)
{
	struct dlm_callback *cb, *safe;

	list_for_each_entry_safe(cb, safe, &lkb->lkb_callbacks, list) {
		list_del(&cb->list);
		kref_put(&cb->ref, dlm_release_callback);
	}

	clear_bit(DLM_IFL_CB_PENDING_BIT, &lkb->lkb_iflags);

	/* invalidate */
	dlm_callback_set_last_ptr(&lkb->lkb_last_cast, NULL);
	dlm_callback_set_last_ptr(&lkb->lkb_last_cb, NULL);
	lkb->lkb_last_bast_mode = -1;
}

int dlm_enqueue_lkb_callback(struct dlm_lkb *lkb, uint32_t flags, int mode,
			     int status, uint32_t sbflags)
{
@@ -181,10 +164,12 @@ void dlm_callback_work(struct work_struct *work)

	spin_lock(&lkb->lkb_cb_lock);
	rv = dlm_dequeue_lkb_callback(lkb, &cb);
	if (WARN_ON_ONCE(rv == DLM_DEQUEUE_CALLBACK_EMPTY)) {
		clear_bit(DLM_IFL_CB_PENDING_BIT, &lkb->lkb_iflags);
		spin_unlock(&lkb->lkb_cb_lock);

	if (WARN_ON_ONCE(rv == DLM_DEQUEUE_CALLBACK_EMPTY))
		goto out;
	}
	spin_unlock(&lkb->lkb_cb_lock);

	for (;;) {
		castfn = lkb->lkb_astfn;
+0 −1
Original line number Diff line number Diff line
@@ -26,7 +26,6 @@ void dlm_callback_set_last_ptr(struct dlm_callback **from,
			       struct dlm_callback *to);

void dlm_release_callback(struct kref *ref);
void dlm_purge_lkb_callbacks(struct dlm_lkb *lkb);
void dlm_callback_work(struct work_struct *work);
int dlm_callback_start(struct dlm_ls *ls);
void dlm_callback_stop(struct dlm_ls *ls);
+1 −1
Original line number Diff line number Diff line
@@ -246,7 +246,7 @@ struct dlm_lkb {
	int8_t			lkb_highbast;	/* highest mode bast sent for */

	int8_t			lkb_wait_type;	/* type of reply waiting for */
	int8_t			lkb_wait_count;
	atomic_t		lkb_wait_count;
	int			lkb_wait_nodeid; /* for debugging */

	struct list_head	lkb_statequeue;	/* rsb g/c/w list */
+16 −20
Original line number Diff line number Diff line
@@ -1407,6 +1407,7 @@ static int add_to_waiters(struct dlm_lkb *lkb, int mstype, int to_nodeid)
{
	struct dlm_ls *ls = lkb->lkb_resource->res_ls;
	int error = 0;
	int wc;

	mutex_lock(&ls->ls_waiters_mutex);

@@ -1428,20 +1429,17 @@ static int add_to_waiters(struct dlm_lkb *lkb, int mstype, int to_nodeid)
			error = -EBUSY;
			goto out;
		}
		lkb->lkb_wait_count++;
		wc = atomic_inc_return(&lkb->lkb_wait_count);
		hold_lkb(lkb);

		log_debug(ls, "addwait %x cur %d overlap %d count %d f %x",
			  lkb->lkb_id, lkb->lkb_wait_type, mstype,
			  lkb->lkb_wait_count, dlm_iflags_val(lkb));
			  lkb->lkb_id, lkb->lkb_wait_type, mstype, wc,
			  dlm_iflags_val(lkb));
		goto out;
	}

	DLM_ASSERT(!lkb->lkb_wait_count,
		   dlm_print_lkb(lkb);
		   printk("wait_count %d\n", lkb->lkb_wait_count););

	lkb->lkb_wait_count++;
	wc = atomic_fetch_inc(&lkb->lkb_wait_count);
	DLM_ASSERT(!wc, dlm_print_lkb(lkb); printk("wait_count %d\n", wc););
	lkb->lkb_wait_type = mstype;
	lkb->lkb_wait_nodeid = to_nodeid; /* for debugging */
	hold_lkb(lkb);
@@ -1504,7 +1502,7 @@ static int _remove_from_waiters(struct dlm_lkb *lkb, int mstype,
		log_debug(ls, "remwait %x convert_reply zap overlap_cancel",
			  lkb->lkb_id);
		lkb->lkb_wait_type = 0;
		lkb->lkb_wait_count--;
		atomic_dec(&lkb->lkb_wait_count);
		unhold_lkb(lkb);
		goto out_del;
	}
@@ -1531,16 +1529,15 @@ static int _remove_from_waiters(struct dlm_lkb *lkb, int mstype,
	if (overlap_done && lkb->lkb_wait_type) {
		log_error(ls, "remwait error %x reply %d wait_type %d overlap",
			  lkb->lkb_id, mstype, lkb->lkb_wait_type);
		lkb->lkb_wait_count--;
		atomic_dec(&lkb->lkb_wait_count);
		unhold_lkb(lkb);
		lkb->lkb_wait_type = 0;
	}

	DLM_ASSERT(lkb->lkb_wait_count, dlm_print_lkb(lkb););
	DLM_ASSERT(atomic_read(&lkb->lkb_wait_count), dlm_print_lkb(lkb););

	clear_bit(DLM_IFL_RESEND_BIT, &lkb->lkb_iflags);
	lkb->lkb_wait_count--;
	if (!lkb->lkb_wait_count)
	if (atomic_dec_and_test(&lkb->lkb_wait_count))
		list_del_init(&lkb->lkb_wait_reply);
	unhold_lkb(lkb);
	return 0;
@@ -2669,7 +2666,7 @@ static int validate_lock_args(struct dlm_ls *ls, struct dlm_lkb *lkb,
			goto out;

		/* lock not allowed if there's any op in progress */
		if (lkb->lkb_wait_type || lkb->lkb_wait_count)
		if (lkb->lkb_wait_type || atomic_read(&lkb->lkb_wait_count))
			goto out;

		if (is_overlap(lkb))
@@ -2731,7 +2728,7 @@ static int validate_unlock_args(struct dlm_lkb *lkb, struct dlm_args *args)

	/* normal unlock not allowed if there's any op in progress */
	if (!(args->flags & (DLM_LKF_CANCEL | DLM_LKF_FORCEUNLOCK)) &&
	    (lkb->lkb_wait_type || lkb->lkb_wait_count))
	    (lkb->lkb_wait_type || atomic_read(&lkb->lkb_wait_count)))
		goto out;

	/* an lkb may be waiting for an rsb lookup to complete where the
@@ -4616,7 +4613,7 @@ static void _receive_message(struct dlm_ls *ls, struct dlm_message *ms,
{
	int error = 0, noent = 0;

	if (!dlm_is_member(ls, le32_to_cpu(ms->m_header.h_nodeid))) {
	if (WARN_ON_ONCE(!dlm_is_member(ls, le32_to_cpu(ms->m_header.h_nodeid)))) {
		log_limit(ls, "receive %d from non-member %d %x %x %d",
			  le32_to_cpu(ms->m_type),
			  le32_to_cpu(ms->m_header.h_nodeid),
@@ -4754,7 +4751,7 @@ static void dlm_receive_message(struct dlm_ls *ls, struct dlm_message *ms,
		/* If we were a member of this lockspace, left, and rejoined,
		   other nodes may still be sending us messages from the
		   lockspace generation before we left. */
		if (!ls->ls_generation) {
		if (WARN_ON_ONCE(!ls->ls_generation)) {
			log_limit(ls, "receive %d from %d ignore old gen",
				  le32_to_cpu(ms->m_type), nodeid);
			return;
@@ -5066,10 +5063,9 @@ int dlm_recover_waiters_post(struct dlm_ls *ls)
		/* drop all wait_count references we still
		 * hold a reference for this iteration.
		 */
		while (lkb->lkb_wait_count) {
			lkb->lkb_wait_count--;
		while (!atomic_dec_and_test(&lkb->lkb_wait_count))
			unhold_lkb(lkb);
		}

		mutex_lock(&ls->ls_waiters_mutex);
		list_del_init(&lkb->lkb_wait_reply);
		mutex_unlock(&ls->ls_waiters_mutex);
+0 −12
Original line number Diff line number Diff line
@@ -935,15 +935,3 @@ void dlm_stop_lockspaces(void)
		log_print("dlm user daemon left %d lockspaces", count);
}
void dlm_stop_lockspaces_check(void)
{
	struct dlm_ls *ls;

	spin_lock(&lslist_lock);
	list_for_each_entry(ls, &lslist, ls_list) {
		if (WARN_ON(!rwsem_is_locked(&ls->ls_in_recovery) ||
			    !dlm_locking_stopped(ls)))
			break;
	}
	spin_unlock(&lslist_lock);
}
Loading