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: Jeffrey Altman <jaltman@auristor.com>
Signed-off-by: David Howells <dhowells@redhat.com>
This commit is contained in:
David Howells 2020-05-27 15:52:02 +01:00
Родитель e49c7b2f6d
Коммит 44746355cc
2 изменённых файлов: 2 добавлений и 54 удалений

Просмотреть файл

@ -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;
}
/*

Просмотреть файл

@ -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;
};