Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5c0dea09 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mfasheh/ocfs2:
  ocfs2: Fix NULL pointer dereferences in o2net
  ocfs2/dlm: dlm_thread should not sleep while holding the dlm_spinlock
  ocfs2/dlm: Print message showing the recovery master
  ocfs2/dlm: Add missing dlm_lockres_put()s
  ocfs2/dlm: Add missing dlm_lockres_put()s in migration path
  ocfs2/dlm: Add missing dlm_lock_put()s
  ocfs2: Fix an endian bug in online resize.
  [PATCH] [OCFS2]: constify function pointer tables
  ocfs2: Fix endian bug in o2dlm protocol negotiation.
  ocfs2: Use dlm_print_one_lock_resource for lock resource print
  [PATCH] fs/ocfs2/dlm/dlmdomain.c: fix printk warning
parents dae311b4 cdef59a9
Loading
Loading
Loading
Loading
+4 −5
Original line number Diff line number Diff line
@@ -451,9 +451,9 @@ static void o2net_set_nn_state(struct o2net_node *nn,
		/* delay if we're withing a RECONNECT_DELAY of the
		 * last attempt */
		delay = (nn->nn_last_connect_attempt +
			 msecs_to_jiffies(o2net_reconnect_delay(sc->sc_node)))
			 msecs_to_jiffies(o2net_reconnect_delay(NULL)))
			- jiffies;
		if (delay > msecs_to_jiffies(o2net_reconnect_delay(sc->sc_node)))
		if (delay > msecs_to_jiffies(o2net_reconnect_delay(NULL)))
			delay = 0;
		mlog(ML_CONN, "queueing conn attempt in %lu jiffies\n", delay);
		queue_delayed_work(o2net_wq, &nn->nn_connect_work, delay);
@@ -1552,12 +1552,11 @@ static void o2net_connect_expired(struct work_struct *work)

	spin_lock(&nn->nn_lock);
	if (!nn->nn_sc_valid) {
		struct o2nm_node *node = nn->nn_sc->sc_node;
		mlog(ML_ERROR, "no connection established with node %u after "
		     "%u.%u seconds, giving up and returning errors.\n",
		     o2net_num_from_nn(nn),
		     o2net_idle_timeout(node) / 1000,
		     o2net_idle_timeout(node) % 1000);
		     o2net_idle_timeout(NULL) / 1000,
		     o2net_idle_timeout(NULL) % 1000);

		o2net_set_nn_state(nn, NULL, 0, -ENOTCONN);
	}
+12 −9
Original line number Diff line number Diff line
@@ -176,6 +176,7 @@ struct dlm_mig_lockres_priv
{
	struct dlm_lock_resource *lockres;
	u8 real_master;
	u8 extra_ref;
};

struct dlm_assert_master_priv
@@ -602,9 +603,7 @@ enum dlm_query_join_response_code {
	JOIN_PROTOCOL_MISMATCH,
};

union dlm_query_join_response {
	u32 intval;
	struct {
struct dlm_query_join_packet {
	u8 code;	/* Response code.  dlm_minor and fs_minor
			   are only valid if this is JOIN_OK */
	u8 dlm_minor;	/* The minor version of the protocol the
@@ -612,7 +611,11 @@ union dlm_query_join_response {
	u8 fs_minor;	/* The minor version of the protocol the
			   filesystem is speaking. */
	u8 reserved;
	} packet;
};

union dlm_query_join_response {
	u32 intval;
	struct dlm_query_join_packet packet;
};

struct dlm_lock_request
+1 −1
Original line number Diff line number Diff line
@@ -487,7 +487,7 @@ int dlm_convert_lock_handler(struct o2net_msg *msg, u32 len, void *data,
			       "cookie=%u:%llu\n",
		     dlm_get_lock_cookie_node(be64_to_cpu(cnv->cookie)),
		     dlm_get_lock_cookie_seq(be64_to_cpu(cnv->cookie)));
		__dlm_print_one_lock_resource(res);
		dlm_print_one_lock_resource(res);
		goto leave;
	}

+66 −37
Original line number Diff line number Diff line
@@ -713,14 +713,46 @@ static int dlm_query_join_proto_check(char *proto_type, int node,
	return rc;
}

/*
 * struct dlm_query_join_packet is made up of four one-byte fields.  They
 * are effectively in big-endian order already.  However, little-endian
 * machines swap them before putting the packet on the wire (because
 * query_join's response is a status, and that status is treated as a u32
 * on the wire).  Thus, a big-endian and little-endian machines will treat
 * this structure differently.
 *
 * The solution is to have little-endian machines swap the structure when
 * converting from the structure to the u32 representation.  This will
 * result in the structure having the correct format on the wire no matter
 * the host endian format.
 */
static void dlm_query_join_packet_to_wire(struct dlm_query_join_packet *packet,
					  u32 *wire)
{
	union dlm_query_join_response response;

	response.packet = *packet;
	*wire = cpu_to_be32(response.intval);
}

static void dlm_query_join_wire_to_packet(u32 wire,
					  struct dlm_query_join_packet *packet)
{
	union dlm_query_join_response response;

	response.intval = cpu_to_be32(wire);
	*packet = response.packet;
}

static int dlm_query_join_handler(struct o2net_msg *msg, u32 len, void *data,
				  void **ret_data)
{
	struct dlm_query_join_request *query;
	union dlm_query_join_response response = {
		.packet.code = JOIN_DISALLOW,
	struct dlm_query_join_packet packet = {
		.code = JOIN_DISALLOW,
	};
	struct dlm_ctxt *dlm = NULL;
	u32 response;
	u8 nodenum;

	query = (struct dlm_query_join_request *) msg->buf;
@@ -737,11 +769,11 @@ static int dlm_query_join_handler(struct o2net_msg *msg, u32 len, void *data,
		mlog(0, "node %u is not in our live map yet\n",
		     query->node_idx);

		response.packet.code = JOIN_DISALLOW;
		packet.code = JOIN_DISALLOW;
		goto respond;
	}

	response.packet.code = JOIN_OK_NO_MAP;
	packet.code = JOIN_OK_NO_MAP;

	spin_lock(&dlm_domain_lock);
	dlm = __dlm_lookup_domain_full(query->domain, query->name_len);
@@ -760,7 +792,7 @@ static int dlm_query_join_handler(struct o2net_msg *msg, u32 len, void *data,
				mlog(0, "disallow join as node %u does not "
				     "have node %u in its nodemap\n",
				     query->node_idx, nodenum);
				response.packet.code = JOIN_DISALLOW;
				packet.code = JOIN_DISALLOW;
				goto unlock_respond;
			}
		}
@@ -780,23 +812,23 @@ static int dlm_query_join_handler(struct o2net_msg *msg, u32 len, void *data,
			/*If this is a brand new context and we
			 * haven't started our join process yet, then
			 * the other node won the race. */
			response.packet.code = JOIN_OK_NO_MAP;
			packet.code = JOIN_OK_NO_MAP;
		} else if (dlm->joining_node != DLM_LOCK_RES_OWNER_UNKNOWN) {
			/* Disallow parallel joins. */
			response.packet.code = JOIN_DISALLOW;
			packet.code = JOIN_DISALLOW;
		} else if (dlm->reco.state & DLM_RECO_STATE_ACTIVE) {
			mlog(0, "node %u trying to join, but recovery "
			     "is ongoing.\n", bit);
			response.packet.code = JOIN_DISALLOW;
			packet.code = JOIN_DISALLOW;
		} else if (test_bit(bit, dlm->recovery_map)) {
			mlog(0, "node %u trying to join, but it "
			     "still needs recovery.\n", bit);
			response.packet.code = JOIN_DISALLOW;
			packet.code = JOIN_DISALLOW;
		} else if (test_bit(bit, dlm->domain_map)) {
			mlog(0, "node %u trying to join, but it "
			     "is still in the domain! needs recovery?\n",
			     bit);
			response.packet.code = JOIN_DISALLOW;
			packet.code = JOIN_DISALLOW;
		} else {
			/* Alright we're fully a part of this domain
			 * so we keep some state as to who's joining
@@ -807,19 +839,15 @@ static int dlm_query_join_handler(struct o2net_msg *msg, u32 len, void *data,
			if (dlm_query_join_proto_check("DLM", bit,
						       &dlm->dlm_locking_proto,
						       &query->dlm_proto)) {
				response.packet.code =
					JOIN_PROTOCOL_MISMATCH;
				packet.code = JOIN_PROTOCOL_MISMATCH;
			} else if (dlm_query_join_proto_check("fs", bit,
							      &dlm->fs_locking_proto,
							      &query->fs_proto)) {
				response.packet.code =
					JOIN_PROTOCOL_MISMATCH;
				packet.code = JOIN_PROTOCOL_MISMATCH;
			} else {
				response.packet.dlm_minor =
					query->dlm_proto.pv_minor;
				response.packet.fs_minor =
					query->fs_proto.pv_minor;
				response.packet.code = JOIN_OK;
				packet.dlm_minor = query->dlm_proto.pv_minor;
				packet.fs_minor = query->fs_proto.pv_minor;
				packet.code = JOIN_OK;
				__dlm_set_joining_node(dlm, query->node_idx);
			}
		}
@@ -830,9 +858,10 @@ static int dlm_query_join_handler(struct o2net_msg *msg, u32 len, void *data,
	spin_unlock(&dlm_domain_lock);

respond:
	mlog(0, "We respond with %u\n", response.packet.code);
	mlog(0, "We respond with %u\n", packet.code);

	return response.intval;
	dlm_query_join_packet_to_wire(&packet, &response);
	return response;
}

static int dlm_assert_joined_handler(struct o2net_msg *msg, u32 len, void *data,
@@ -937,7 +966,7 @@ static int dlm_send_join_cancels(struct dlm_ctxt *dlm,
			 sizeof(unsigned long))) {
		mlog(ML_ERROR,
		     "map_size %u != BITS_TO_LONGS(O2NM_MAX_NODES) %u\n",
		     map_size, BITS_TO_LONGS(O2NM_MAX_NODES));
		     map_size, (unsigned)BITS_TO_LONGS(O2NM_MAX_NODES));
		return -EINVAL;
	}

@@ -968,7 +997,8 @@ static int dlm_request_join(struct dlm_ctxt *dlm,
{
	int status;
	struct dlm_query_join_request join_msg;
	union dlm_query_join_response join_resp;
	struct dlm_query_join_packet packet;
	u32 join_resp;

	mlog(0, "querying node %d\n", node);

@@ -984,11 +1014,12 @@ static int dlm_request_join(struct dlm_ctxt *dlm,

	status = o2net_send_message(DLM_QUERY_JOIN_MSG, DLM_MOD_KEY, &join_msg,
				    sizeof(join_msg), node,
				    &join_resp.intval);
				    &join_resp);
	if (status < 0 && status != -ENOPROTOOPT) {
		mlog_errno(status);
		goto bail;
	}
	dlm_query_join_wire_to_packet(join_resp, &packet);

	/* -ENOPROTOOPT from the net code means the other side isn't
	    listening for our message type -- that's fine, it means
@@ -997,10 +1028,10 @@ static int dlm_request_join(struct dlm_ctxt *dlm,
	if (status == -ENOPROTOOPT) {
		status = 0;
		*response = JOIN_OK_NO_MAP;
	} else if (join_resp.packet.code == JOIN_DISALLOW ||
		   join_resp.packet.code == JOIN_OK_NO_MAP) {
		*response = join_resp.packet.code;
	} else if (join_resp.packet.code == JOIN_PROTOCOL_MISMATCH) {
	} else if (packet.code == JOIN_DISALLOW ||
		   packet.code == JOIN_OK_NO_MAP) {
		*response = packet.code;
	} else if (packet.code == JOIN_PROTOCOL_MISMATCH) {
		mlog(ML_NOTICE,
		     "This node requested DLM locking protocol %u.%u and "
		     "filesystem locking protocol %u.%u.  At least one of "
@@ -1012,14 +1043,12 @@ static int dlm_request_join(struct dlm_ctxt *dlm,
		     dlm->fs_locking_proto.pv_minor,
		     node);
		status = -EPROTO;
		*response = join_resp.packet.code;
	} else if (join_resp.packet.code == JOIN_OK) {
		*response = join_resp.packet.code;
		*response = packet.code;
	} else if (packet.code == JOIN_OK) {
		*response = packet.code;
		/* Use the same locking protocol as the remote node */
		dlm->dlm_locking_proto.pv_minor =
			join_resp.packet.dlm_minor;
		dlm->fs_locking_proto.pv_minor =
			join_resp.packet.fs_minor;
		dlm->dlm_locking_proto.pv_minor = packet.dlm_minor;
		dlm->fs_locking_proto.pv_minor = packet.fs_minor;
		mlog(0,
		     "Node %d responds JOIN_OK with DLM locking protocol "
		     "%u.%u and fs locking protocol %u.%u\n",
@@ -1031,7 +1060,7 @@ static int dlm_request_join(struct dlm_ctxt *dlm,
	} else {
		status = -EINVAL;
		mlog(ML_ERROR, "invalid response %d from node %u\n",
		     join_resp.packet.code, node);
		     packet.code, node);
	}

	mlog(0, "status %d, node %d response is %d\n", status, node,
+15 −3
Original line number Diff line number Diff line
@@ -1663,7 +1663,12 @@ int dlm_master_request_handler(struct o2net_msg *msg, u32 len, void *data,
		dlm_put_mle(tmpmle);
	}
send_response:

	/*
	 * __dlm_lookup_lockres() grabbed a reference to this lockres.
	 * The reference is released by dlm_assert_master_worker() under
	 * the call to dlm_dispatch_assert_master().  If
	 * dlm_assert_master_worker() isn't called, we drop it here.
	 */
	if (dispatch_assert) {
		if (response != DLM_MASTER_RESP_YES)
			mlog(ML_ERROR, "invalid response %d\n", response);
@@ -1678,7 +1683,11 @@ int dlm_master_request_handler(struct o2net_msg *msg, u32 len, void *data,
		if (ret < 0) {
			mlog(ML_ERROR, "failed to dispatch assert master work\n");
			response = DLM_MASTER_RESP_ERROR;
			dlm_lockres_put(res);
		}
	} else {
		if (res)
			dlm_lockres_put(res);
	}

	dlm_put(dlm);
@@ -2348,7 +2357,7 @@ int dlm_deref_lockres_handler(struct o2net_msg *msg, u32 len, void *data,
			mlog(ML_ERROR, "%s:%.*s: node %u trying to drop ref "
		     	"but it is already dropped!\n", dlm->name,
		     	res->lockname.len, res->lockname.name, node);
			__dlm_print_one_lock_resource(res);
			dlm_print_one_lock_resource(res);
		}
		ret = 0;
		goto done;
@@ -2408,7 +2417,7 @@ static void dlm_deref_lockres_worker(struct dlm_work_item *item, void *data)
		mlog(ML_ERROR, "%s:%.*s: node %u trying to drop ref "
		     "but it is already dropped!\n", dlm->name,
		     res->lockname.len, res->lockname.name, node);
		__dlm_print_one_lock_resource(res);
		dlm_print_one_lock_resource(res);
	}

	dlm_lockres_put(res);
@@ -2933,6 +2942,9 @@ static void dlm_remove_nonlocal_locks(struct dlm_ctxt *dlm,
				dlm_lockres_clear_refmap_bit(lock->ml.node, res);
				list_del_init(&lock->list);
				dlm_lock_put(lock);
				/* In a normal unlock, we would have added a
				 * DLM_UNLOCK_FREE_LOCK action. Force it. */
				dlm_lock_put(lock);
			}
		}
		queue++;
Loading