fs/afs/vl_probe.c

Source file repositories/reference/linux-study-clean/fs/afs/vl_probe.c

File Facts

System
Linux kernel
Corpus path
fs/afs/vl_probe.c
Extension
.c
Size
8225 bytes
Lines
311
Domain
Core OS
Bucket
VFS And Filesystem Core
Inferred role
Core OS: implementation source
Status
source implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

if (!(server->probe.flags & AFS_VLSERVER_PROBE_RESPONDED)) {
			server->probe.abort_code = call->abort_code;
			server->probe.error = ret;
		}
		goto responded;
	case -ENOMEM:
	case -ENONET:
	case -EKEYEXPIRED:
	case -EKEYREVOKED:
	case -EKEYREJECTED:
		server->probe.flags |= AFS_VLSERVER_PROBE_LOCAL_FAILURE;
		if (server->probe.error == 0)
			server->probe.error = ret;
		trace_afs_io_error(call->debug_id, ret, afs_io_error_vl_probe_fail);
		goto out;
	case -ECONNRESET: /* Responded, but call expired. */
	case -ERFKILL:
	case -EADDRNOTAVAIL:
	case -ENETUNREACH:
	case -EHOSTUNREACH:
	case -EHOSTDOWN:
	case -ECONNREFUSED:
	case -ETIMEDOUT:
	case -ETIME:
	default:
		clear_bit(index, &alist->responded);
		set_bit(index, &alist->probe_failed);
		if (!(server->probe.flags & AFS_VLSERVER_PROBE_RESPONDED) &&
		    (server->probe.error == 0 ||
		     server->probe.error == -ETIMEDOUT ||
		     server->probe.error == -ETIME))
			server->probe.error = ret;
		trace_afs_io_error(call->debug_id, ret, afs_io_error_vl_probe_fail);
		goto out;
	}

responded:
	set_bit(index, &alist->responded);
	clear_bit(index, &alist->probe_failed);

	if (call->service_id == YFS_VL_SERVICE) {
		server->probe.flags |= AFS_VLSERVER_PROBE_IS_YFS;
		set_bit(AFS_VLSERVER_FL_IS_YFS, &server->flags);
		server->service_id = call->service_id;
	} else {
		server->probe.flags |= AFS_VLSERVER_PROBE_NOT_YFS;
		if (!(server->probe.flags & AFS_VLSERVER_PROBE_IS_YFS)) {
			clear_bit(AFS_VLSERVER_FL_IS_YFS, &server->flags);
			server->service_id = call->service_id;
		}
	}

	rtt_us = rxrpc_kernel_get_srtt(addr->peer);
	if (rtt_us < server->probe.rtt) {
		server->probe.rtt = rtt_us;
		server->rtt = rtt_us;
		alist->preferred = index;
	}

	smp_wmb(); /* Set rtt before responded. */
	server->probe.flags |= AFS_VLSERVER_PROBE_RESPONDED;
	set_bit(AFS_VLSERVER_FL_PROBED, &server->flags);
	set_bit(AFS_VLSERVER_FL_RESPONDING, &server->flags);
	have_result = true;
out:
	spin_unlock(&server->probe_lock);

	trace_afs_vl_probe(server, false, alist, index, call->error, call->abort_code, rtt_us);
	_debug("probe [%u][%u] %pISpc rtt=%d ret=%d",
	       server_index, index, rxrpc_kernel_remote_addr(addr->peer),
	       rtt_us, ret);

	afs_done_one_vl_probe(server, have_result);
}

/*
 * Probe all of a vlserver's addresses to find out the best route and to
 * query its capabilities.
 */
static bool afs_do_probe_vlserver(struct afs_net *net,
				  struct afs_vlserver *server,
				  struct key *key,
				  unsigned int server_index,
				  struct afs_error *_e)
{
	struct afs_addr_list *alist;
	struct afs_call *call;
	unsigned long unprobed;
	unsigned int index, i;
	bool in_progress = false;

Annotation

Implementation Notes