Commit 98f9fda2 authored by David Howells's avatar David Howells
Browse files

afs: Fold the afs_addr_cursor struct in



Fold the afs_addr_cursor struct into the afs_operation struct and the
afs_vl_cursor struct and fold its operations into their callers also.

Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: linux-afs@lists.infradead.org
parent e38f299e
Loading
Loading
Loading
Loading
+0 −53
Original line number Diff line number Diff line
@@ -375,56 +375,3 @@ int afs_merge_fs_addr6(struct afs_net *net, struct afs_addr_list *alist,
	alist->nr_addrs++;
	return 0;
}

/*
 * Get an address to try.
 */
bool afs_iterate_addresses(struct afs_addr_cursor *ac)
{
	unsigned long set, failed;
	int index;

	if (!ac->alist)
		return false;

	set = ac->alist->responded;
	failed = ac->alist->probe_failed;
	_enter("%lx-%lx-%lx,%d", set, failed, ac->tried, ac->index);

	ac->nr_iterations++;

	set &= ~(failed | ac->tried);

	if (!set)
		return false;

	index = READ_ONCE(ac->alist->preferred);
	if (test_bit(index, &set))
		goto selected;

	index = __ffs(set);

selected:
	ac->index = index;
	set_bit(index, &ac->tried);
	ac->call_responded = false;
	return true;
}

/*
 * Release an address list cursor.
 */
void afs_end_cursor(struct afs_addr_cursor *ac)
{
	struct afs_addr_list *alist;

	alist = ac->alist;
	if (alist) {
		if (ac->call_responded &&
		    ac->index != alist->preferred &&
		    test_bit(ac->alist->preferred, &ac->tried))
			WRITE_ONCE(alist->preferred, ac->index);
		afs_put_addrlist(alist, afs_alist_trace_put_end_cursor);
		ac->alist = NULL;
	}
}
+17 −4
Original line number Diff line number Diff line
@@ -179,6 +179,7 @@ void afs_wait_for_operation(struct afs_operation *op)
	_enter("");

	while (afs_select_fileserver(op)) {
		op->call_responded = false;
		op->call_error = 0;
		op->call_abort_code = 0;
		op->cb_s_break = op->server->cb_s_break;
@@ -191,17 +192,19 @@ void afs_wait_for_operation(struct afs_operation *op)
			op->call_error = -ENOTSUPP;

		if (op->call) {
			afs_wait_for_call_to_complete(op->call, &op->ac);
			afs_wait_for_call_to_complete(op->call);
			op->call_abort_code = op->call->abort_code;
			op->call_error = op->call->error;
			op->call_responded = op->call->responded;
			op->ac.call_responded = true;
			WRITE_ONCE(op->ac.alist->addrs[op->ac.index].last_error,
			WRITE_ONCE(op->alist->addrs[op->addr_index].last_error,
				   op->call_error);
			afs_put_call(op->call);
		}
	}

	if (op->call_responded)
		set_bit(AFS_SERVER_FL_RESPONDING, &op->server->flags);

	if (!afs_op_error(op)) {
		_debug("success");
		op->ops->success(op);
@@ -227,6 +230,7 @@ void afs_wait_for_operation(struct afs_operation *op)
 */
int afs_put_operation(struct afs_operation *op)
{
	struct afs_addr_list *alist;
	int i, ret = afs_op_error(op);

	_enter("op=%08x,%d", op->debug_id, ret);
@@ -249,7 +253,16 @@ int afs_put_operation(struct afs_operation *op)
		kfree(op->more_files);
	}

	afs_end_cursor(&op->ac);
	alist = op->alist;
	if (alist) {
		if (op->call_responded &&
		    op->addr_index != alist->preferred &&
		    test_bit(alist->preferred, &op->addr_tried))
			WRITE_ONCE(alist->preferred, op->addr_index);
		afs_put_addrlist(alist, afs_alist_trace_put_operation);
		op->alist = NULL;
	}

	afs_put_serverlist(op->net, op->server_list);
	afs_put_volume(op->net, op->volume, afs_volume_trace_put_put_op);
	key_put(op->key);
+19 −22
Original line number Diff line number Diff line
@@ -74,11 +74,9 @@ static void afs_done_one_fs_probe(struct afs_net *net, struct afs_server *server
 */
static void afs_fs_probe_not_done(struct afs_net *net,
				  struct afs_server *server,
				  struct afs_addr_cursor *ac)
				  struct afs_addr_list *alist,
				  int index)
{
	struct afs_addr_list *alist = ac->alist;
	unsigned int index = ac->index;

	_enter("");

	trace_afs_io_error(0, -ENOMEM, afs_io_error_fs_probe_fail);
@@ -100,10 +98,10 @@ static void afs_fs_probe_not_done(struct afs_net *net,
 */
void afs_fileserver_probe_result(struct afs_call *call)
{
	struct afs_addr_list *alist = call->alist;
	struct afs_address *addr = &alist->addrs[call->addr_ix];
	struct afs_addr_list *alist = call->probe_alist;
	struct afs_address *addr = &alist->addrs[call->probe_index];
	struct afs_server *server = call->server;
	unsigned int index = call->addr_ix;
	unsigned int index = call->probe_index;
	unsigned int rtt_us = 0, cap0;
	int ret = call->error;

@@ -196,37 +194,36 @@ void afs_fileserver_probe_result(struct afs_call *call)
void afs_fs_probe_fileserver(struct afs_net *net, struct afs_server *server,
			     struct key *key, bool all)
{
	struct afs_addr_cursor ac = {
		.index = 0,
	};
	struct afs_addr_list *alist;
	unsigned int index;

	_enter("%pU", &server->uuid);

	read_lock(&server->fs_lock);
	ac.alist = rcu_dereference_protected(server->addresses,
	alist = rcu_dereference_protected(server->addresses,
					  lockdep_is_held(&server->fs_lock));
	afs_get_addrlist(ac.alist, afs_alist_trace_get_probe);
	afs_get_addrlist(alist, afs_alist_trace_get_probe);
	read_unlock(&server->fs_lock);

	server->probed_at = jiffies;
	atomic_set(&server->probe_outstanding, all ? ac.alist->nr_addrs : 1);
	atomic_set(&server->probe_outstanding, all ? alist->nr_addrs : 1);
	memset(&server->probe, 0, sizeof(server->probe));
	server->probe.rtt = UINT_MAX;

	ac.index = ac.alist->preferred;
	if (ac.index < 0 || ac.index >= ac.alist->nr_addrs)
	index = alist->preferred;
	if (index < 0 || index >= alist->nr_addrs)
		all = true;

	if (all) {
		for (ac.index = 0; ac.index < ac.alist->nr_addrs; ac.index++)
			if (!afs_fs_get_capabilities(net, server, &ac, key))
				afs_fs_probe_not_done(net, server, &ac);
		for (index = 0; index < alist->nr_addrs; index++)
			if (!afs_fs_get_capabilities(net, server, alist, index, key))
				afs_fs_probe_not_done(net, server, alist, index);
	} else {
		if (!afs_fs_get_capabilities(net, server, &ac, key))
			afs_fs_probe_not_done(net, server, &ac);
		if (!afs_fs_get_capabilities(net, server, alist, index, key))
			afs_fs_probe_not_done(net, server, alist, index);
	}

	afs_put_addrlist(ac.alist, afs_alist_trace_put_probe);
	afs_put_addrlist(alist, afs_alist_trace_put_probe);
}

/*
+20 −11
Original line number Diff line number Diff line
@@ -1605,10 +1605,8 @@ static const struct afs_call_type afs_RXFSGiveUpAllCallBacks = {
/*
 * Flush all the callbacks we have on a server.
 */
int afs_fs_give_up_all_callbacks(struct afs_net *net,
				 struct afs_server *server,
				 struct afs_addr_cursor *ac,
				 struct key *key)
int afs_fs_give_up_all_callbacks(struct afs_net *net, struct afs_server *server,
				 struct afs_address *addr, struct key *key)
{
	struct afs_call *call;
	__be32 *bp;
@@ -1621,7 +1619,7 @@ int afs_fs_give_up_all_callbacks(struct afs_net *net,
		return -ENOMEM;

	call->key	= key;
	call->peer	= rxrpc_kernel_get_peer(ac->alist->addrs[ac->index].peer);
	call->peer	= rxrpc_kernel_get_peer(addr->peer);
	call->service_id = server->service_id;

	/* marshall the parameters */
@@ -1629,9 +1627,11 @@ int afs_fs_give_up_all_callbacks(struct afs_net *net,
	*bp++ = htonl(FSGIVEUPALLCALLBACKS);

	call->server = afs_use_server(server, afs_server_trace_give_up_cb);
	afs_make_call(ac, call, GFP_NOFS);
	afs_wait_for_call_to_complete(call, ac);
	afs_make_call(call, GFP_NOFS);
	afs_wait_for_call_to_complete(call);
	ret = call->error;
	if (call->responded)
		set_bit(AFS_SERVER_FL_RESPONDING, &server->flags);
	afs_put_call(call);
	return ret;
}
@@ -1695,6 +1695,12 @@ static int afs_deliver_fs_get_capabilities(struct afs_call *call)
	return 0;
}

static void afs_fs_get_capabilities_destructor(struct afs_call *call)
{
	afs_put_addrlist(call->probe_alist, afs_alist_trace_put_getcaps);
	afs_flat_call_destructor(call);
}

/*
 * FS.GetCapabilities operation type
 */
@@ -1703,7 +1709,7 @@ static const struct afs_call_type afs_RXFSGetCapabilities = {
	.op		= afs_FS_GetCapabilities,
	.deliver	= afs_deliver_fs_get_capabilities,
	.done		= afs_fileserver_probe_result,
	.destructor	= afs_flat_call_destructor,
	.destructor	= afs_fs_get_capabilities_destructor,
};

/*
@@ -1713,7 +1719,8 @@ static const struct afs_call_type afs_RXFSGetCapabilities = {
 * ->done() - otherwise we return false to indicate we didn't even try.
 */
bool afs_fs_get_capabilities(struct afs_net *net, struct afs_server *server,
			     struct afs_addr_cursor *ac, struct key *key)
			     struct afs_addr_list *alist, unsigned int addr_index,
			     struct key *key)
{
	struct afs_call *call;
	__be32 *bp;
@@ -1726,7 +1733,9 @@ bool afs_fs_get_capabilities(struct afs_net *net, struct afs_server *server,

	call->key	= key;
	call->server	= afs_use_server(server, afs_server_trace_get_caps);
	call->peer	= rxrpc_kernel_get_peer(ac->alist->addrs[ac->index].peer);
	call->peer	= rxrpc_kernel_get_peer(alist->addrs[addr_index].peer);
	call->probe_alist = afs_get_addrlist(alist, afs_alist_trace_get_getcaps);
	call->probe_index = addr_index;
	call->service_id = server->service_id;
	call->upgrade	= true;
	call->async	= true;
@@ -1737,7 +1746,7 @@ bool afs_fs_get_capabilities(struct afs_net *net, struct afs_server *server,
	*bp++ = htonl(FSGETCAPABILITIES);

	trace_afs_make_fs_call(call, NULL);
	afs_make_call(ac, call, GFP_NOFS);
	afs_make_call(call, GFP_NOFS);
	afs_put_call(call);
	return true;
}
+28 −30
Original line number Diff line number Diff line
@@ -102,7 +102,6 @@ struct afs_addr_list {
 */
struct afs_call {
	const struct afs_call_type *type;	/* type of call */
	struct afs_addr_list	*alist;		/* Address is alist[addr_ix] */
	wait_queue_head_t	waitq;		/* processes awaiting completion */
	struct work_struct	async_work;	/* async I/O processor */
	struct work_struct	work;		/* actual work processor */
@@ -123,6 +122,10 @@ struct afs_call {
	};
	void			*buffer;	/* reply receive buffer */
	union {
		struct {
			struct afs_addr_list	*probe_alist;
			unsigned char		probe_index;	/* Address in ->probe_alist */
		};
		struct afs_addr_list	*ret_alist;
		struct afs_vldb_entry	*ret_vldb;
		char			*ret_str;
@@ -139,7 +142,6 @@ struct afs_call {
	unsigned		reply_max;	/* maximum size of reply */
	unsigned		count2;		/* count used in unmarshalling */
	unsigned char		unmarshall;	/* unmarshalling phase */
	unsigned char		addr_ix;	/* Address in ->alist */
	bool			drop_ref;	/* T if need to drop ref for incoming call */
	bool			need_attention;	/* T if RxRPC poked us */
	bool			async;		/* T if asynchronous */
@@ -729,31 +731,23 @@ struct afs_error {
	bool	aborted;		/* T if ->error is from an abort */
};

/*
 * Cursor for iterating over a server's address list.
 */
struct afs_addr_cursor {
	struct afs_addr_list	*alist;		/* Current address list (pins ref) */
	unsigned long		tried;		/* Tried addresses */
	signed char		index;		/* Current address */
	unsigned short		nr_iterations;	/* Number of address iterations */
	bool			call_responded;
};

/*
 * Cursor for iterating over a set of volume location servers.
 */
struct afs_vl_cursor {
	struct afs_addr_cursor	ac;
	struct afs_cell		*cell;		/* The cell we're querying */
	struct afs_vlserver_list *server_list;	/* Current server list (pins ref) */
	struct afs_vlserver	*server;	/* Server on which this resides */
	struct afs_addr_list	*alist;		/* Current address list (pins ref) */
	struct key		*key;		/* Key for the server */
	unsigned long		untried_servers; /* Bitmask of untried servers */
	unsigned long		addr_tried;	/* Tried addresses */
	struct afs_error	cumul_error;	/* Cumulative error */
	unsigned int		debug_id;
	s32			call_abort_code;
	short			call_error;	/* Error from single call */
	short			server_index;	/* Current server */
	signed char		addr_index;	/* Current address */
	unsigned short		flags;
#define AFS_VL_CURSOR_STOP	0x0001		/* Set to cease iteration */
#define AFS_VL_CURSOR_RETRY	0x0002		/* Set to do a retry */
@@ -812,8 +806,6 @@ struct afs_operation {
	struct timespec64	ctime;		/* Change time to set */
	struct afs_error	cumul_error;	/* Cumulative error */
	short			nr_files;	/* Number of entries in file[], more_files */
	short			call_error;	/* Error from single call */
	s32			call_abort_code; /* Abort code from single call */
	unsigned int		debug_id;

	unsigned int		cb_v_break;	/* Volume break counter before op */
@@ -862,16 +854,19 @@ struct afs_operation {
	};

	/* Fileserver iteration state */
	struct afs_addr_cursor	ac;
	struct afs_server_list	*server_list;	/* Current server list (pins ref) */
	struct afs_server	*server;	/* Server we're using (ref pinned by server_list) */
	struct afs_addr_list	*alist;		/* Current address list (pins ref) */
	struct afs_call		*call;
	unsigned long		untried_servers; /* Bitmask of untried servers */
	unsigned long		addr_tried;	/* Tried addresses */
	s32			call_abort_code; /* Abort code from single call */
	short			call_error;	/* Error from single call */
	short			server_index;	/* Current server */
	short			nr_iterations;	/* Number of server iterations */
	signed char		addr_index;	/* Current address */
	bool			call_responded;	/* T if the current address responded */


	unsigned int		flags;
#define AFS_OPERATION_STOP		0x0001	/* Set to cease iteration */
#define AFS_OPERATION_VBUSY		0x0002	/* Set if seen VBUSY */
@@ -981,8 +976,6 @@ extern struct afs_vlserver_list *afs_parse_text_addrs(struct afs_net *,
bool afs_addr_list_same(const struct afs_addr_list *a,
			const struct afs_addr_list *b);
extern struct afs_vlserver_list *afs_dns_query(struct afs_cell *, time64_t *);
extern bool afs_iterate_addresses(struct afs_addr_cursor *);
extern void afs_end_cursor(struct afs_addr_cursor *ac);

extern int afs_merge_fs_addr4(struct afs_net *net, struct afs_addr_list *addr,
			      __be32 xdr, u16 port);
@@ -1123,10 +1116,11 @@ extern void afs_fs_get_volume_status(struct afs_operation *);
extern void afs_fs_set_lock(struct afs_operation *);
extern void afs_fs_extend_lock(struct afs_operation *);
extern void afs_fs_release_lock(struct afs_operation *);
extern int afs_fs_give_up_all_callbacks(struct afs_net *, struct afs_server *,
					struct afs_addr_cursor *, struct key *);
extern bool afs_fs_get_capabilities(struct afs_net *, struct afs_server *,
				    struct afs_addr_cursor *, struct key *);
int afs_fs_give_up_all_callbacks(struct afs_net *net, struct afs_server *server,
				 struct afs_address *addr, struct key *key);
bool afs_fs_get_capabilities(struct afs_net *net, struct afs_server *server,
			     struct afs_addr_list *alist, unsigned int addr_index,
			     struct key *key);
extern void afs_fs_inline_bulk_status(struct afs_operation *);

struct afs_acl {
@@ -1306,8 +1300,8 @@ extern int __net_init afs_open_socket(struct afs_net *);
extern void __net_exit afs_close_socket(struct afs_net *);
extern void afs_charge_preallocation(struct work_struct *);
extern void afs_put_call(struct afs_call *);
extern void afs_make_call(struct afs_addr_cursor *, struct afs_call *, gfp_t);
void afs_wait_for_call_to_complete(struct afs_call *call, struct afs_addr_cursor *ac);
void afs_make_call(struct afs_call *call, gfp_t gfp);
void afs_wait_for_call_to_complete(struct afs_call *call);
extern struct afs_call *afs_alloc_flat_call(struct afs_net *,
					    const struct afs_call_type *,
					    size_t, size_t);
@@ -1325,9 +1319,9 @@ static inline void afs_make_op_call(struct afs_operation *op, struct afs_call *c
	call->op	= op;
	call->key	= op->key;
	call->intr	= !(op->flags & AFS_OPERATION_UNINTR);
	call->peer	= rxrpc_kernel_get_peer(op->ac.alist->addrs[op->ac.index].peer);
	call->peer	= rxrpc_kernel_get_peer(op->alist->addrs[op->addr_index].peer);
	call->service_id = op->server->service_id;
	afs_make_call(&op->ac, call, gfp);
	afs_make_call(call, gfp);
}

static inline void afs_extract_begin(struct afs_call *call, void *buf, size_t size)
@@ -1493,8 +1487,12 @@ extern void afs_fs_exit(void);
extern struct afs_vldb_entry *afs_vl_get_entry_by_name_u(struct afs_vl_cursor *,
							 const char *, int);
extern struct afs_addr_list *afs_vl_get_addrs_u(struct afs_vl_cursor *, const uuid_t *);
extern struct afs_call *afs_vl_get_capabilities(struct afs_net *, struct afs_addr_cursor *,
						struct key *, struct afs_vlserver *, unsigned int);
struct afs_call *afs_vl_get_capabilities(struct afs_net *net,
					 struct afs_addr_list *alist,
					 unsigned int addr_index,
					 struct key *key,
					 struct afs_vlserver *server,
					 unsigned int server_index);
extern struct afs_addr_list *afs_yfsvl_get_endpoints(struct afs_vl_cursor *, const uuid_t *);
extern char *afs_yfsvl_get_cell_name(struct afs_vl_cursor *);

Loading