mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 10:41:38 -04:00
AFS fixes
-----BEGIN PGP SIGNATURE-----
iQIVAwUAXN2BC/u3V2unywtrAQJm9w/+L7ufbRkj6XGVongmhf4n+auBQXMJ4jec
zN6bjWrp/SN9kJfOqOKA+sk9s3cCOCV8SF/2eM5P8DJNtrB6aXlg590u1wSkOp99
FdSM8Fy7v4bTwW9hCBhvcFpC+layVUEv/WAsCCIZi94W+H43XFY4QM79cqoqIx8r
nTLu9EcjWFpUoBIAYEU0x/h4IA5Cyl6CUw3YZhZYaGoLLfi9EZkgBLlUU+6OXpDO
Uepzn1gnpXMCNsiBE/Hr9LR0pfOTtzdJuNADrppRnbPfky8RsPE8tuk6kT6301U1
IxG66SafYsvbQGzyIdfTydl022DFj5LOtCPFtfALviJqdBOGE/zPPnrBPinHg4oJ
40P2tIJ/+Ksz5cPzmkA1KanSXaQ2v0sLBVdQJ7yt5EFuAMzj/roWpiPmEmQd6KqB
ixZdZLehKFPaAB5cR41fHV1jB30HN7oakwqCoYmXd1Chu3AlB15yV9WZMSqjPS8P
pkNC/X5mU5hDnZUx9e3Fbu8LqoGOjnGvDn5jOxihdKfaGu3A4OlbSerIUbRHvnT8
u8XDPoq4j61f04MiI9z/bPDFTRYyycIQPcHYQpi4MJt9lSkkydP217P60BJsUv2n
NIPYwgI7VIse0Gdo8shIg+RnSnJaKHT9Sf86h8pyDFO6wZp/GVVqPSdjjU+Lv5fv
CZGJ7PCYcfs=
=2q2Y
-----END PGP SIGNATURE-----
Merge tag 'afs-fixes-20190516' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs
Pull misc AFS fixes from David Howells:
"This fixes a set of miscellaneous issues in the afs filesystem,
including:
- leak of keys on file close.
- broken error handling in xattr functions.
- missing locking when updating VL server list.
- volume location server DNS lookup whereby preloaded cells may not
ever get a lookup and regular DNS lookups to maintain server lists
consume power unnecessarily.
- incorrect error propagation and handling in the fileserver
iteration code causes operations to sometimes apparently succeed.
- interruption of server record check/update side op during
fileserver iteration causes uninterruptible main operations to fail
unexpectedly.
- callback promise expiry time miscalculation.
- over invalidation of the callback promise on directories.
- double locking on callback break waking up file locking waiters.
- double increment of the vnode callback break counter.
Note that it makes some changes outside of the afs code, including:
- an extra parameter to dns_query() to allow the dns_resolver key
just accessed to be immediately invalidated. AFS is caching the
results itself, so the key can be discarded.
- an interruptible version of wait_var_event().
- an rxrpc function to allow the maximum lifespan to be set on a
call.
- a way for an rxrpc call to be marked as non-interruptible"
* tag 'afs-fixes-20190516' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs:
afs: Fix double inc of vnode->cb_break
afs: Fix lock-wait/callback-break double locking
afs: Don't invalidate callback if AFS_VNODE_DIR_VALID not set
afs: Fix calculation of callback expiry time
afs: Make dynamic root population wait uninterruptibly for proc_cells_lock
afs: Make some RPC operations non-interruptible
rxrpc: Allow the kernel to mark a call as being non-interruptible
afs: Fix error propagation from server record check/update
afs: Fix the maximum lifespan of VL and probe calls
rxrpc: Provide kernel interface to set max lifespan on a call
afs: Fix "kAFS: AFS vnode with undefined type 0"
afs: Fix cell DNS lookup
Add wait_var_event_interruptible()
dns_resolver: Allow used keys to be invalidated
afs: Fix afs_cell records to always have a VL server list record
afs: Fix missing lock when replacing VL server list
afs: Fix afs_xattr_get_yfs() to not try freeing an error value
afs: Fix incorrect error handling in afs_xattr_get_acl()
afs: Fix key leak in afs_release() and afs_evict_inode()
This commit is contained in:
commit
227747fb9e
37 changed files with 478 additions and 296 deletions
|
|
@ -1887,7 +1887,7 @@ static int ceph_dns_resolve_name(const char *name, size_t namelen,
|
|||
return -EINVAL;
|
||||
|
||||
/* do dns_resolve upcall */
|
||||
ip_len = dns_query(NULL, name, end - name, NULL, &ip_addr, NULL);
|
||||
ip_len = dns_query(NULL, name, end - name, NULL, &ip_addr, NULL, false);
|
||||
if (ip_len > 0)
|
||||
ret = ceph_pton(ip_addr, ip_len, addr, -1, NULL);
|
||||
else
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@
|
|||
* @options: Request options (or NULL if no options)
|
||||
* @_result: Where to place the returned data (or NULL)
|
||||
* @_expiry: Where to store the result expiry time (or NULL)
|
||||
* @invalidate: Always invalidate the key after use
|
||||
*
|
||||
* The data will be returned in the pointer at *result, if provided, and the
|
||||
* caller is responsible for freeing it.
|
||||
|
|
@ -69,7 +70,8 @@
|
|||
* Returns the size of the result on success, -ve error code otherwise.
|
||||
*/
|
||||
int dns_query(const char *type, const char *name, size_t namelen,
|
||||
const char *options, char **_result, time64_t *_expiry)
|
||||
const char *options, char **_result, time64_t *_expiry,
|
||||
bool invalidate)
|
||||
{
|
||||
struct key *rkey;
|
||||
struct user_key_payload *upayload;
|
||||
|
|
@ -157,6 +159,8 @@ int dns_query(const char *type, const char *name, size_t namelen,
|
|||
ret = len;
|
||||
put:
|
||||
up_read(&rkey->sem);
|
||||
if (invalidate)
|
||||
key_invalidate(rkey);
|
||||
key_put(rkey);
|
||||
out:
|
||||
kleave(" = %d", ret);
|
||||
|
|
|
|||
|
|
@ -270,6 +270,7 @@ static int rxrpc_listen(struct socket *sock, int backlog)
|
|||
* @gfp: The allocation constraints
|
||||
* @notify_rx: Where to send notifications instead of socket queue
|
||||
* @upgrade: Request service upgrade for call
|
||||
* @intr: The call is interruptible
|
||||
* @debug_id: The debug ID for tracing to be assigned to the call
|
||||
*
|
||||
* Allow a kernel service to begin a call on the nominated socket. This just
|
||||
|
|
@ -287,6 +288,7 @@ struct rxrpc_call *rxrpc_kernel_begin_call(struct socket *sock,
|
|||
gfp_t gfp,
|
||||
rxrpc_notify_rx_t notify_rx,
|
||||
bool upgrade,
|
||||
bool intr,
|
||||
unsigned int debug_id)
|
||||
{
|
||||
struct rxrpc_conn_parameters cp;
|
||||
|
|
@ -311,6 +313,7 @@ struct rxrpc_call *rxrpc_kernel_begin_call(struct socket *sock,
|
|||
memset(&p, 0, sizeof(p));
|
||||
p.user_call_ID = user_call_ID;
|
||||
p.tx_total_len = tx_total_len;
|
||||
p.intr = intr;
|
||||
|
||||
memset(&cp, 0, sizeof(cp));
|
||||
cp.local = rx->local;
|
||||
|
|
@ -443,6 +446,31 @@ void rxrpc_kernel_new_call_notification(
|
|||
}
|
||||
EXPORT_SYMBOL(rxrpc_kernel_new_call_notification);
|
||||
|
||||
/**
|
||||
* rxrpc_kernel_set_max_life - Set maximum lifespan on a call
|
||||
* @sock: The socket the call is on
|
||||
* @call: The call to configure
|
||||
* @hard_timeout: The maximum lifespan of the call in jiffies
|
||||
*
|
||||
* Set the maximum lifespan of a call. The call will end with ETIME or
|
||||
* ETIMEDOUT if it takes longer than this.
|
||||
*/
|
||||
void rxrpc_kernel_set_max_life(struct socket *sock, struct rxrpc_call *call,
|
||||
unsigned long hard_timeout)
|
||||
{
|
||||
unsigned long now;
|
||||
|
||||
mutex_lock(&call->user_mutex);
|
||||
|
||||
now = jiffies;
|
||||
hard_timeout += now;
|
||||
WRITE_ONCE(call->expect_term_by, hard_timeout);
|
||||
rxrpc_reduce_call_timer(call, hard_timeout, now, rxrpc_timer_set_for_hard);
|
||||
|
||||
mutex_unlock(&call->user_mutex);
|
||||
}
|
||||
EXPORT_SYMBOL(rxrpc_kernel_set_max_life);
|
||||
|
||||
/*
|
||||
* connect an RxRPC socket
|
||||
* - this just targets it at a specific destination; no actual connection
|
||||
|
|
|
|||
|
|
@ -482,6 +482,7 @@ enum rxrpc_call_flag {
|
|||
RXRPC_CALL_BEGAN_RX_TIMER, /* We began the expect_rx_by timer */
|
||||
RXRPC_CALL_RX_HEARD, /* The peer responded at least once to this call */
|
||||
RXRPC_CALL_RX_UNDERRUN, /* Got data underrun */
|
||||
RXRPC_CALL_IS_INTR, /* The call is interruptible */
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -711,6 +712,7 @@ struct rxrpc_call_params {
|
|||
u32 normal; /* Max time since last call packet (msec) */
|
||||
} timeouts;
|
||||
u8 nr_timeouts; /* Number of timeouts specified */
|
||||
bool intr; /* The call is interruptible */
|
||||
};
|
||||
|
||||
struct rxrpc_send_params {
|
||||
|
|
|
|||
|
|
@ -241,6 +241,8 @@ struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx,
|
|||
return call;
|
||||
}
|
||||
|
||||
if (p->intr)
|
||||
__set_bit(RXRPC_CALL_IS_INTR, &call->flags);
|
||||
call->tx_total_len = p->tx_total_len;
|
||||
trace_rxrpc_call(call, rxrpc_call_new_client, atomic_read(&call->usage),
|
||||
here, (const void *)p->user_call_ID);
|
||||
|
|
|
|||
|
|
@ -656,10 +656,14 @@ static int rxrpc_wait_for_channel(struct rxrpc_call *call, gfp_t gfp)
|
|||
|
||||
add_wait_queue_exclusive(&call->waitq, &myself);
|
||||
for (;;) {
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
if (test_bit(RXRPC_CALL_IS_INTR, &call->flags))
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
else
|
||||
set_current_state(TASK_UNINTERRUPTIBLE);
|
||||
if (call->call_id)
|
||||
break;
|
||||
if (signal_pending(current)) {
|
||||
if (test_bit(RXRPC_CALL_IS_INTR, &call->flags) &&
|
||||
signal_pending(current)) {
|
||||
ret = -ERESTARTSYS;
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -80,7 +80,8 @@ static int rxrpc_wait_for_tx_window_nonintr(struct rxrpc_sock *rx,
|
|||
if (call->state >= RXRPC_CALL_COMPLETE)
|
||||
return call->error;
|
||||
|
||||
if (timeout == 0 &&
|
||||
if (test_bit(RXRPC_CALL_IS_INTR, &call->flags) &&
|
||||
timeout == 0 &&
|
||||
tx_win == tx_start && signal_pending(current))
|
||||
return -EINTR;
|
||||
|
||||
|
|
@ -620,6 +621,7 @@ int rxrpc_do_sendmsg(struct rxrpc_sock *rx, struct msghdr *msg, size_t len)
|
|||
.call.tx_total_len = -1,
|
||||
.call.user_call_ID = 0,
|
||||
.call.nr_timeouts = 0,
|
||||
.call.intr = true,
|
||||
.abort_code = 0,
|
||||
.command = RXRPC_CMD_SEND_DATA,
|
||||
.exclusive = false,
|
||||
|
|
|
|||
Loading…
Reference in a new issue