Commit e7506d34 authored by David S. Miller's avatar David S. Miller
Browse files


David Howells says:

====================
rxrpc fixes
Here are some fixes for AF_RXRPC:

 (1) Fix the handling of ICMP/ICMP6 packets.  This is a problem due to
     rxrpc being switched to acting as a UDP tunnel, thereby allowing it to
     steal the packets before they go through the UDP Rx queue.  UDP
     tunnels can't get ICMP/ICMP6 packets, however.  This patch adds an
     additional encap hook so that they can.

 (2) Fix the encryption routines in rxkad to handle packets that have more
     than three parts correctly.  The problem is that ->nr_frags doesn't
     count the initial fragment, so the sglist ends up too short.

 (3) Fix a problem with destruction of the local endpoint potentially
     getting repeated.

 (4) Fix the calculation of the time at which to resend.
     jiffies_to_usecs() gives microseconds, not nanoseconds.

 (5) Fix AFS to work out when callback promises and locks expire based on
     the time an op was issued rather than the time the first reply packet
     arrives.  We don't know how long the server took between calculating
     the expiry interval and transmitting the reply.

 (6) Given (5), rxrpc_get_reply_time() is no longer used, so remove it.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 32614006 21457f4a
Loading
Loading
Loading
Loading
+0 −11
Original line number Diff line number Diff line
@@ -1055,17 +1055,6 @@ The kernel interface functions are as follows:
     first function to change.  Note that this must be called in TASK_RUNNING
     state.

 (#) Get reply timestamp::

	bool rxrpc_kernel_get_reply_time(struct socket *sock,
					 struct rxrpc_call *call,
					 ktime_t *_ts)

     This allows the timestamp on the first DATA packet of the reply of a
     client call to be queried, provided that it is still in the Rx ring.  If
     successful, the timestamp will be stored into ``*_ts`` and true will be
     returned; false will be returned otherwise.

 (#) Get remote client epoch::

	u32 rxrpc_kernel_get_epoch(struct socket *sock,
+1 −1
Original line number Diff line number Diff line
@@ -76,7 +76,7 @@ void afs_lock_op_done(struct afs_call *call)
	if (call->error == 0) {
		spin_lock(&vnode->lock);
		trace_afs_flock_ev(vnode, NULL, afs_flock_timestamp, 0);
		vnode->locked_at = call->reply_time;
		vnode->locked_at = call->issue_time;
		afs_schedule_lock_extension(vnode);
		spin_unlock(&vnode->lock);
	}
+1 −1
Original line number Diff line number Diff line
@@ -131,7 +131,7 @@ static void xdr_decode_AFSFetchStatus(const __be32 **_bp,

static time64_t xdr_decode_expiry(struct afs_call *call, u32 expiry)
{
	return ktime_divns(call->reply_time, NSEC_PER_SEC) + expiry;
	return ktime_divns(call->issue_time, NSEC_PER_SEC) + expiry;
}

static void xdr_decode_AFSCallBack(const __be32 **_bp,
+1 −2
Original line number Diff line number Diff line
@@ -137,7 +137,6 @@ struct afs_call {
	bool			need_attention;	/* T if RxRPC poked us */
	bool			async;		/* T if asynchronous */
	bool			upgrade;	/* T to request service upgrade */
	bool			have_reply_time; /* T if have got reply_time */
	bool			intr;		/* T if interruptible */
	bool			unmarshalling_error; /* T if an unmarshalling error occurred */
	u16			service_id;	/* Actual service ID (after upgrade) */
@@ -151,7 +150,7 @@ struct afs_call {
		} __attribute__((packed));
		__be64		tmp64;
	};
	ktime_t			reply_time;	/* Time of first reply packet */
	ktime_t			issue_time;	/* Time of issue of operation */
};

struct afs_call_type {
+1 −6
Original line number Diff line number Diff line
@@ -351,6 +351,7 @@ void afs_make_call(struct afs_addr_cursor *ac, struct afs_call *call, gfp_t gfp)
	if (call->max_lifespan)
		rxrpc_kernel_set_max_life(call->net->socket, rxcall,
					  call->max_lifespan);
	call->issue_time = ktime_get_real();

	/* send the request */
	iov[0].iov_base	= call->request;
@@ -501,12 +502,6 @@ static void afs_deliver_to_call(struct afs_call *call)
			return;
		}

		if (!call->have_reply_time &&
		    rxrpc_kernel_get_reply_time(call->net->socket,
						call->rxcall,
						&call->reply_time))
			call->have_reply_time = true;

		ret = call->type->deliver(call);
		state = READ_ONCE(call->state);
		if (ret == 0 && call->unmarshalling_error)
Loading