mirror of
https://git.openafs.org/openafs.git
synced 2025-01-18 15:00:12 +00:00
afs: Introduce afs_kill_pending()
Introduce a function that checks to see if the current kernel task has a pending kill (e.g. SIGKILL) that will terminate the process when it returns to userspace. Add afs_kill_pending() that uses an osi level function, osi_kill_pending() to determine if the process has a pending termination. If the osi level function has not been implemented, just return 0. Add a Linux implementation of osi_kill_pending() that calls Linux's fatal_signal_pending() (if it's available). Update Linux's "filter_enoent()" function in osi_vnodeops.c to use afs_kill_pending(). A future commit will expand the use of afs_kill_pending(). Fix minor white space in an adjacent lines. Change-Id: Ib215639d36f4baa7a1dffda3cc314d2d447c6e96 Reviewed-on: https://gerrit.openafs.org/15746 Reviewed-by: Andrew Deason <adeason@sinenomine.net> Reviewed-by: Michael Meffie <mmeffie@sinenomine.net> Tested-by: BuildBot <buildbot@rampaginggeek.com>
This commit is contained in:
parent
9d34ceb2dc
commit
840cf3b628
@ -186,3 +186,20 @@ afs_start_thread(void (*proc)(void), char *name, int needs_glock)
|
||||
kthread_run(afs_thread_wrapper, proc, "%s", name);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for a pending fatal signal
|
||||
* Return 1 if a fatal signal is pending, otherwise return 0;
|
||||
*/
|
||||
int
|
||||
osi_kill_pending(void)
|
||||
{
|
||||
#if defined(HAVE_LINUX_FATAL_SIGNAL_PENDING)
|
||||
if (fatal_signal_pending(current)) {
|
||||
return 1;
|
||||
}
|
||||
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25)
|
||||
# error fatal_signal_pending not available, but it should be
|
||||
#endif
|
||||
return 0;
|
||||
}
|
@ -51,6 +51,7 @@ extern int osi_lookupname(char *aname, uio_seg_t seg, int followlink,
|
||||
extern int osi_abspath(char *aname, char *buf, int buflen,
|
||||
int followlink, char **pathp);
|
||||
extern void afs_start_thread(void (*proc)(void), char *name, int needs_glock);
|
||||
extern int osi_kill_pending(void);
|
||||
|
||||
/* osi_probe.c */
|
||||
extern void *osi_find_syscall_table(int which);
|
||||
|
@ -1305,17 +1305,19 @@ parent_vcache_dv(struct inode *inode, cred_t *credp)
|
||||
}
|
||||
return hgetlo(pvcp->f.m.DataVersion);
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure we don't accidentally yield an ENOENT that's caused by internal
|
||||
* errors instead of the requested filename actually not existing. This has been
|
||||
* possible in the past because Linux returns errors for some low-level routines
|
||||
* when the process is dying. Incorrect ENOENT errors can cause bogus negative
|
||||
* dentries to exist, which is very bad, so make sure that doesn't happen.
|
||||
*/
|
||||
static inline int
|
||||
filter_enoent(int code)
|
||||
{
|
||||
#ifdef HAVE_LINUX_FATAL_SIGNAL_PENDING
|
||||
if (code == ENOENT && fatal_signal_pending(current)) {
|
||||
return EINTR;
|
||||
if (code == ENOENT && afs_kill_pending()) {
|
||||
return EINTR;
|
||||
}
|
||||
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25)
|
||||
# error fatal_signal_pending not available, but it should be
|
||||
#endif
|
||||
return code;
|
||||
}
|
||||
|
||||
|
@ -383,6 +383,38 @@ afs_PrintServerErrors(struct vrequest *areq, struct VenusFid *afid)
|
||||
afs_warnuser("%s\n", term);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief
|
||||
* Determine if the current process is pending termination and will be
|
||||
* killed when returning to userspace.
|
||||
*
|
||||
* \retval 1 if the process is dying
|
||||
* \retval 0 if the process is not dying
|
||||
*
|
||||
* \note
|
||||
* If the process is pending termination, there is no need to retry requests
|
||||
* or wait for a server to return data, etc. as the process is going to die
|
||||
* before it can process any data. However we will still need to ensure that
|
||||
* we don't corrupt any locks, cache, etc., or any data that persists in other
|
||||
* processes.
|
||||
*
|
||||
* \note
|
||||
* On some platforms (Linux), a process will not sleep if it is pending
|
||||
* termination. If we can detect that the process will be killed, it is better
|
||||
* to not retry the requests, etc. to avoid spinning the CPU.
|
||||
*/
|
||||
int
|
||||
afs_kill_pending(void)
|
||||
{
|
||||
#if defined(UKERNEL)
|
||||
return 0;
|
||||
#elif defined(AFS_LINUX_ENV)
|
||||
return osi_kill_pending();
|
||||
#else
|
||||
return 0;
|
||||
#endif /* UKERNEL */
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief
|
||||
* Analyze the outcome of an RPC operation, taking whatever support
|
||||
|
@ -11,9 +11,10 @@
|
||||
#define _AFS_PROTOTYPES_H_
|
||||
|
||||
/* afs_analyze.c */
|
||||
extern int afs_kill_pending(void);
|
||||
extern int afs_Analyze(struct afs_conn *aconn, struct rx_connection *rxconn,
|
||||
afs_int32 acode, struct VenusFid *afid,
|
||||
struct vrequest *areq,
|
||||
afs_int32 acode, struct VenusFid *afid,
|
||||
struct vrequest *areq,
|
||||
int op, afs_int32 locktype, struct cell *cellp);
|
||||
|
||||
/* afs_axscache.c */
|
||||
|
Loading…
Reference in New Issue
Block a user