Commit 44746355 authored by David Howells's avatar David Howells
Browse files

afs: Don't get epoch from a server because it may be ambiguous



Don't get the epoch from a server, particularly one that we're looking up
by UUID, as UUIDs may be ambiguous and may map to more than one server - so
we can't draw any conclusions from it.

Reported-by: default avatarJeffrey Altman <jaltman@auristor.com>
Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
parent e49c7b2f
Loading
Loading
Loading
Loading
+2 −47
Original line number Diff line number Diff line
@@ -118,8 +118,6 @@ bool afs_cm_incoming_call(struct afs_call *call)
{
	_enter("{%u, CB.OP %u}", call->service_id, call->operation_ID);

	call->epoch = rxrpc_kernel_get_epoch(call->net->socket, call->rxcall);

	switch (call->operation_ID) {
	case CBCallBack:
		call->type = &afs_SRXCBCallBack;
@@ -149,49 +147,6 @@ bool afs_cm_incoming_call(struct afs_call *call)
	}
}

/*
 * Record a probe to the cache manager from a server.
 */
static int afs_record_cm_probe(struct afs_call *call, struct afs_server *server)
{
	_enter("");

	if (test_bit(AFS_SERVER_FL_HAVE_EPOCH, &server->flags) &&
	    !afs_is_probing_server(server)) {
		if (server->cm_epoch == call->epoch)
			return 0;

		if (!server->probe.said_rebooted) {
			pr_notice("kAFS: FS rebooted %pU\n", &server->uuid);
			server->probe.said_rebooted = true;
		}
	}

	spin_lock(&server->probe_lock);

	if (!test_and_set_bit(AFS_SERVER_FL_HAVE_EPOCH, &server->flags)) {
		server->cm_epoch = call->epoch;
		server->probe.cm_epoch = call->epoch;
		goto out;
	}

	if (server->probe.cm_probed &&
	    call->epoch != server->probe.cm_epoch &&
	    !server->probe.said_inconsistent) {
		pr_notice("kAFS: FS endpoints inconsistent %pU\n",
			  &server->uuid);
		server->probe.said_inconsistent = true;
	}

	if (!server->probe.cm_probed || call->epoch == server->cm_epoch)
		server->probe.cm_epoch = server->cm_epoch;

out:
	server->probe.cm_probed = true;
	spin_unlock(&server->probe_lock);
	return 0;
}

/*
 * Find the server record by peer address and record a probe to the cache
 * manager from a server.
@@ -210,7 +165,7 @@ static int afs_find_cm_server_by_peer(struct afs_call *call)
	}

	call->server = server;
	return afs_record_cm_probe(call, server);
	return 0;
}

/*
@@ -231,7 +186,7 @@ static int afs_find_cm_server_by_uuid(struct afs_call *call,
	}

	call->server = server;
	return afs_record_cm_probe(call, server);
	return 0;
}

/*
+0 −7
Original line number Diff line number Diff line
@@ -124,7 +124,6 @@ struct afs_call {
	spinlock_t		state_lock;
	int			error;		/* error code */
	u32			abort_code;	/* Remote abort ID or 0 */
	u32			epoch;
	unsigned int		max_lifespan;	/* Maximum lifespan to set if not 0 */
	unsigned		request_size;	/* size of request data */
	unsigned		reply_max;	/* maximum size of reply */
@@ -491,12 +490,10 @@ struct afs_server {
#define AFS_SERVER_FL_MAY_HAVE_CB 8		/* May have callbacks on this fileserver */
#define AFS_SERVER_FL_IS_YFS	9		/* Server is YFS not AFS */
#define AFS_SERVER_FL_NO_RM2	10		/* Fileserver doesn't support YFS.RemoveFile2 */
#define AFS_SERVER_FL_HAVE_EPOCH 11		/* ->epoch is valid */
#define AFS_SERVER_FL_NEEDS_UPDATE 12		/* Fileserver address list is out of date */
	atomic_t		ref;		/* Object refcount */
	atomic_t		active;		/* Active user count */
	u32			addr_version;	/* Address list version */
	u32			cm_epoch;	/* Server RxRPC epoch */
	unsigned int		debug_id;	/* Debugging ID for traces */

	/* file service access */
@@ -515,15 +512,11 @@ struct afs_server {
	struct {
		unsigned int	rtt;		/* RTT as ktime/64 */
		u32		abort_code;
		u32		cm_epoch;
		short		error;
		bool		responded:1;
		bool		is_yfs:1;
		bool		not_yfs:1;
		bool		local_failure:1;
		bool		cm_probed:1;
		bool		said_rebooted:1;
		bool		said_inconsistent:1;
	} probe;
};