aboutsummaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2005-10-12 14:43:32 +1000
committerPaul Mackerras <paulus@samba.org>2005-10-12 14:43:32 +1000
commitb6ec995a21a9428aef620b5adf46d047a18d88b8 (patch)
tree6719121e6605cbca524b687f47336b9bbf3b8d41 /kernel
parent3a5f8c5f788d68e325d9fe3c26f4df5a5aee838a (diff)
parentda64c6ee6bb71bfb3f09d9bb89ce1aa4b1ee7e89 (diff)
Merge from Linus' tree
Diffstat (limited to 'kernel')
-rw-r--r--kernel/audit.c2
-rw-r--r--kernel/cpuset.c14
-rw-r--r--kernel/exit.c2
-rw-r--r--kernel/kfifo.c4
-rw-r--r--kernel/power/swsusp.c7
-rw-r--r--kernel/signal.c42
6 files changed, 49 insertions, 22 deletions
diff --git a/kernel/audit.c b/kernel/audit.c
index 83096b67510..aefa73a8a58 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -560,7 +560,7 @@ static void audit_buffer_free(struct audit_buffer *ab)
}
static struct audit_buffer * audit_buffer_alloc(struct audit_context *ctx,
- unsigned int __nocast gfp_mask, int type)
+ gfp_t gfp_mask, int type)
{
unsigned long flags;
struct audit_buffer *ab = NULL;
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index 6a6e87b2f2f..28176d083f7 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -968,8 +968,6 @@ static ssize_t cpuset_common_file_read(struct file *file, char __user *buf,
char *page;
ssize_t retval = 0;
char *s;
- char *start;
- ssize_t n;
if (!(page = (char *)__get_free_page(GFP_KERNEL)))
return -ENOMEM;
@@ -999,15 +997,7 @@ static ssize_t cpuset_common_file_read(struct file *file, char __user *buf,
*s++ = '\n';
*s = '\0';
- start = page + *ppos;
- n = s - start;
-
- /* Do nothing if *ppos is at the eof or beyond the eof. */
- if (n <= 0)
- goto out;
-
- retval = n - copy_to_user(buf, start, min(n, nbytes));
- *ppos += retval;
+ retval = simple_read_from_buffer(buf, nbytes, ppos, page, s - page);
out:
free_page((unsigned long)page);
return retval;
@@ -1680,7 +1670,7 @@ static const struct cpuset *nearest_exclusive_ancestor(const struct cpuset *cs)
* GFP_USER - only nodes in current tasks mems allowed ok.
**/
-int cpuset_zone_allowed(struct zone *z, unsigned int __nocast gfp_mask)
+int cpuset_zone_allowed(struct zone *z, gfp_t gfp_mask)
{
int node; /* node that zone z is on */
const struct cpuset *cs; /* current cpuset ancestors */
diff --git a/kernel/exit.c b/kernel/exit.c
index ee6d8b8abef..43077732619 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -1203,7 +1203,7 @@ static int wait_task_stopped(task_t *p, int delayed_group_leader, int noreap,
exit_code = p->exit_code;
if (unlikely(!exit_code) ||
- unlikely(p->state > TASK_STOPPED))
+ unlikely(p->state & TASK_TRACED))
goto bail_ref;
return wait_noreap_copyout(p, pid, uid,
why, (exit_code << 8) | 0x7f,
diff --git a/kernel/kfifo.c b/kernel/kfifo.c
index 179baafcdd9..64ab045c3d9 100644
--- a/kernel/kfifo.c
+++ b/kernel/kfifo.c
@@ -36,7 +36,7 @@
* struct kfifo with kfree().
*/
struct kfifo *kfifo_init(unsigned char *buffer, unsigned int size,
- unsigned int __nocast gfp_mask, spinlock_t *lock)
+ gfp_t gfp_mask, spinlock_t *lock)
{
struct kfifo *fifo;
@@ -64,7 +64,7 @@ EXPORT_SYMBOL(kfifo_init);
*
* The size will be rounded-up to a power of 2.
*/
-struct kfifo *kfifo_alloc(unsigned int size, unsigned int __nocast gfp_mask, spinlock_t *lock)
+struct kfifo *kfifo_alloc(unsigned int size, gfp_t gfp_mask, spinlock_t *lock)
{
unsigned char *buffer;
struct kfifo *ret;
diff --git a/kernel/power/swsusp.c b/kernel/power/swsusp.c
index acf79ac1cb6..2d5c4567644 100644
--- a/kernel/power/swsusp.c
+++ b/kernel/power/swsusp.c
@@ -1095,7 +1095,7 @@ static inline void eat_page(void *page)
*eaten_memory = c;
}
-static unsigned long get_usable_page(unsigned gfp_mask)
+unsigned long get_usable_page(unsigned gfp_mask)
{
unsigned long m;
@@ -1109,7 +1109,7 @@ static unsigned long get_usable_page(unsigned gfp_mask)
return m;
}
-static void free_eaten_memory(void)
+void free_eaten_memory(void)
{
unsigned long m;
void **c;
@@ -1481,11 +1481,12 @@ static int read_suspend_image(void)
/* Allocate memory for the image and read the data from swap */
error = check_pagedir(pagedir_nosave);
- free_eaten_memory();
+
if (!error)
error = data_read(pagedir_nosave);
if (error) { /* We fail cleanly */
+ free_eaten_memory();
for_each_pbe (p, pagedir_nosave)
if (p->address) {
free_page(p->address);
diff --git a/kernel/signal.c b/kernel/signal.c
index 5a274705ba1..50c99264377 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -262,7 +262,7 @@ next_signal(struct sigpending *pending, sigset_t *mask)
return sig;
}
-static struct sigqueue *__sigqueue_alloc(struct task_struct *t, unsigned int __nocast flags,
+static struct sigqueue *__sigqueue_alloc(struct task_struct *t, gfp_t flags,
int override_rlimit)
{
struct sigqueue *q = NULL;
@@ -578,7 +578,8 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info)
* is to alert stop-signal processing code when another
* processor has come along and cleared the flag.
*/
- tsk->signal->flags |= SIGNAL_STOP_DEQUEUED;
+ if (!(tsk->signal->flags & SIGNAL_GROUP_EXIT))
+ tsk->signal->flags |= SIGNAL_STOP_DEQUEUED;
}
if ( signr &&
((info->si_code & __SI_MASK) == __SI_TIMER) &&
@@ -1192,6 +1193,40 @@ kill_proc_info(int sig, struct siginfo *info, pid_t pid)
return error;
}
+/* like kill_proc_info(), but doesn't use uid/euid of "current" */
+int kill_proc_info_as_uid(int sig, struct siginfo *info, pid_t pid,
+ uid_t uid, uid_t euid)
+{
+ int ret = -EINVAL;
+ struct task_struct *p;
+
+ if (!valid_signal(sig))
+ return ret;
+
+ read_lock(&tasklist_lock);
+ p = find_task_by_pid(pid);
+ if (!p) {
+ ret = -ESRCH;
+ goto out_unlock;
+ }
+ if ((!info || ((unsigned long)info != 1 &&
+ (unsigned long)info != 2 && SI_FROMUSER(info)))
+ && (euid != p->suid) && (euid != p->uid)
+ && (uid != p->suid) && (uid != p->uid)) {
+ ret = -EPERM;
+ goto out_unlock;
+ }
+ if (sig && p->sighand) {
+ unsigned long flags;
+ spin_lock_irqsave(&p->sighand->siglock, flags);
+ ret = __group_send_sig_info(sig, info, p);
+ spin_unlock_irqrestore(&p->sighand->siglock, flags);
+ }
+out_unlock:
+ read_unlock(&tasklist_lock);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(kill_proc_info_as_uid);
/*
* kill_something_info() interprets pid in interesting ways just like kill(2).
@@ -1763,7 +1798,8 @@ do_signal_stop(int signr)
* stop is always done with the siglock held,
* so this check has no races.
*/
- if (t->state < TASK_STOPPED) {
+ if (!t->exit_state &&
+ !(t->state & (TASK_STOPPED|TASK_TRACED))) {
stop_count++;
signal_wake_up(t, 0);
}