cfs_sigset_t cfs_get_blocked_sigs(void);
cfs_sigset_t cfs_block_allsigs(void);
cfs_sigset_t cfs_block_sigs(cfs_sigset_t bits);
+cfs_sigset_t cfs_block_sigsinv(unsigned long sigs);
void cfs_restore_sigs(cfs_sigset_t);
int cfs_signal_pending(void);
void cfs_clear_sigpending(void);
+
/*
* XXX Liang:
* these macros should be removed in the future,
return old;
}
+/* Block all signals except for the @sigs. It's only used in
+ * Linux kernel, just a dummy here. */
+cfs_sigset_t cfs_block_sigsinv(unsigned long sigs)
+{
+ cfs_sigset_t old = 0;
+ return old;
+}
+
void cfs_restore_sigs(cfs_sigset_t old)
{
}
return old;
}
+/* Block all signals except for the @sigs */
+cfs_sigset_t
+cfs_block_sigsinv(unsigned long sigs)
+{
+ unsigned long flags;
+ cfs_sigset_t old;
+
+ SIGNAL_MASK_LOCK(current, flags);
+ old = current->blocked;
+ siginitsetinv(¤t->blocked, sigs);
+ RECALC_SIGPENDING;
+ SIGNAL_MASK_UNLOCK(current, flags);
+
+ return old;
+}
+
void
cfs_restore_sigs (cfs_sigset_t old)
{
EXPORT_SYMBOL(cfs_daemonize_ctxt);
EXPORT_SYMBOL(cfs_block_allsigs);
EXPORT_SYMBOL(cfs_block_sigs);
+EXPORT_SYMBOL(cfs_block_sigsinv);
EXPORT_SYMBOL(cfs_restore_sigs);
EXPORT_SYMBOL(cfs_signal_pending);
EXPORT_SYMBOL(cfs_clear_sigpending);
return old;
}
+/* Block all signals except for the @sigs. It's only used in
+ * Linux kernel, just a dummy here. */
+cfs_sigset_t cfs_block_sigsinv(unsigned long sigs)
+{
+ cfs_sigset_t old;
+ int rc;
+
+ /* Return old blocked sigs */
+ rc = sigprocmask(SIG_SETMASK, NULL, &old);
+ LASSERT(rc == 0);
+
+ return old;
+}
+
void cfs_restore_sigs(cfs_sigset_t old)
{
int rc = sigprocmask(SIG_SETMASK, &old, NULL);
return 0;
}
+/* Block all signals except for the @sigs. It's only used in
+ * Linux kernel, just a dummy here. */
+cfs_sigset_t cfs_block_sigsinv(unsigned long sigs)
+{
+ return 0;
+}
+
void cfs_restore_sigs(cfs_sigset_t old)
{
}
sigmask(SIGTERM) | sigmask(SIGQUIT) | \
sigmask(SIGALRM) | sigmask(SIGHUP))
-#ifdef __KERNEL__
-static inline sigset_t l_w_e_set_sigs(sigset_t sigs)
-{
- sigset_t old = 0;
-
- /* XXX Liang: how to change sigmask in Darwin8.x?
- * there is syscall like pthread_sigmask() but we cannot
- * use in kernel */
-#if !defined(__DARWIN8__)
- struct proc *p = current_proc();
- extern int block_procsigmask(struct proc *p, int bit);
- old = cfs_current()->uu_sigmask;
- block_procsigmask(p, ~sigs);
-#endif
-
- return old;
-}
-#endif
-
#endif
sigmask(SIGALRM))
#ifdef __KERNEL__
-static inline sigset_t l_w_e_set_sigs(int sigs)
-{
- sigset_t old;
- unsigned long irqflags;
-
- SIGNAL_MASK_LOCK(current, irqflags);
- old = current->blocked;
- siginitsetinv(¤t->blocked, sigs);
- RECALC_SIGPENDING;
- SIGNAL_MASK_UNLOCK(current, irqflags);
-
- return old;
-}
-#endif
-
-#ifdef __KERNEL__
/* initialize ost_lvb according to inode */
static inline void inode_init_lvb(struct inode *inode, struct ost_lvb *lvb)
{
\
/* Block all signals (just the non-fatal ones if no timeout). */ \
if (info->lwi_on_signal != NULL && (__timeout == 0 || __allow_intr)) \
- __blocked = l_w_e_set_sigs(LUSTRE_FATAL_SIGS); \
+ __blocked = cfs_block_sigsinv(LUSTRE_FATAL_SIGS); \
else \
- __blocked = l_w_e_set_sigs(0); \
+ __blocked = cfs_block_sigsinv(0); \
\
for (;;) { \
unsigned __wstate; \
} \
/* Take signals after the timeout expires. */ \
if (info->lwi_on_signal != NULL) \
- (void)l_w_e_set_sigs(LUSTRE_FATAL_SIGS); \
+ (void)cfs_block_sigsinv(LUSTRE_FATAL_SIGS);\
} \
} \
\
int cl_lock_state_wait(const struct lu_env *env, struct cl_lock *lock)
{
cfs_waitlink_t waiter;
+ cfs_sigset_t blocked;
int result;
ENTRY;
cl_lock_trace(D_DLMTRACE, env, "state wait lock", lock);
result = lock->cll_error;
if (result == 0) {
+ /* To avoid being interrupted by the 'non-fatal' signals
+ * (SIGCHLD, for instance), we'd block them temporarily.
+ * LU-305 */
+ blocked = cfs_block_sigsinv(LUSTRE_FATAL_SIGS);
+
cfs_waitlink_init(&waiter);
cfs_waitq_add(&lock->cll_wq, &waiter);
cfs_set_current_state(CFS_TASK_INTERRUPTIBLE);
cfs_set_current_state(CFS_TASK_RUNNING);
cfs_waitq_del(&lock->cll_wq, &waiter);
result = cfs_signal_pending() ? -EINTR : 0;
+
+ /* Restore old blocked signals */
+ cfs_restore_sigs(blocked);
}
RETURN(result);
}
waited);
/* Cannot use l_event_wait() for an interruptible sleep. */
waited += 3;
- blocked = l_w_e_set_sigs(sigmask(SIGKILL));
+ blocked = cfs_block_sigsinv(sigmask(SIGKILL));
cfs_waitq_wait_event_interruptible_timeout(
waitq,
(atomic_read(&mnt->mnt_count) == 1),