Commit 41f9d29f authored by Al Viro's avatar Al Viro

trimming task_work: kill ->data

get rid of the only user of ->data; this is _not_ the final variant - in the
end we'll have task_work and rcu_head identical and just use cred->rcu,
at which point the separate allocation will be gone completely.
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 72667028
...@@ -10,14 +10,12 @@ typedef void (*task_work_func_t)(struct task_work *); ...@@ -10,14 +10,12 @@ typedef void (*task_work_func_t)(struct task_work *);
struct task_work { struct task_work {
struct hlist_node hlist; struct hlist_node hlist;
task_work_func_t func; task_work_func_t func;
void *data;
}; };
static inline void static inline void
init_task_work(struct task_work *twork, task_work_func_t func, void *data) init_task_work(struct task_work *twork, task_work_func_t func)
{ {
twork->func = func; twork->func = func;
twork->data = data;
} }
int task_work_add(struct task_struct *task, struct task_work *twork, bool); int task_work_add(struct task_struct *task, struct task_work *twork, bool);
......
...@@ -830,7 +830,7 @@ static int irq_thread(void *data) ...@@ -830,7 +830,7 @@ static int irq_thread(void *data)
sched_setscheduler(current, SCHED_FIFO, &param); sched_setscheduler(current, SCHED_FIFO, &param);
init_task_work(&on_exit_work, irq_thread_dtor, NULL); init_task_work(&on_exit_work, irq_thread_dtor);
task_work_add(current, &on_exit_work, false); task_work_add(current, &on_exit_work, false);
while (!irq_wait_for_interrupt(action)) { while (!irq_wait_for_interrupt(action)) {
......
...@@ -148,6 +148,10 @@ extern key_ref_t lookup_user_key(key_serial_t id, unsigned long flags, ...@@ -148,6 +148,10 @@ extern key_ref_t lookup_user_key(key_serial_t id, unsigned long flags,
#define KEY_LOOKUP_PARTIAL 0x02 #define KEY_LOOKUP_PARTIAL 0x02
#define KEY_LOOKUP_FOR_UNLINK 0x04 #define KEY_LOOKUP_FOR_UNLINK 0x04
struct kludge { /* this will die off very soon */
struct task_work twork;
struct cred *cred;
};
extern long join_session_keyring(const char *name); extern long join_session_keyring(const char *name);
extern void key_change_session_keyring(struct task_work *twork); extern void key_change_session_keyring(struct task_work *twork);
......
...@@ -1456,7 +1456,8 @@ long keyctl_session_to_parent(void) ...@@ -1456,7 +1456,8 @@ long keyctl_session_to_parent(void)
{ {
struct task_struct *me, *parent; struct task_struct *me, *parent;
const struct cred *mycred, *pcred; const struct cred *mycred, *pcred;
struct task_work *newwork, *oldwork; struct kludge *newwork;
struct task_work *oldwork;
key_ref_t keyring_r; key_ref_t keyring_r;
struct cred *cred; struct cred *cred;
int ret; int ret;
...@@ -1466,7 +1467,7 @@ long keyctl_session_to_parent(void) ...@@ -1466,7 +1467,7 @@ long keyctl_session_to_parent(void)
return PTR_ERR(keyring_r); return PTR_ERR(keyring_r);
ret = -ENOMEM; ret = -ENOMEM;
newwork = kmalloc(sizeof(struct task_work), GFP_KERNEL); newwork = kmalloc(sizeof(struct kludge), GFP_KERNEL);
if (!newwork) if (!newwork)
goto error_keyring; goto error_keyring;
...@@ -1478,7 +1479,8 @@ long keyctl_session_to_parent(void) ...@@ -1478,7 +1479,8 @@ long keyctl_session_to_parent(void)
goto error_newwork; goto error_newwork;
cred->tgcred->session_keyring = key_ref_to_ptr(keyring_r); cred->tgcred->session_keyring = key_ref_to_ptr(keyring_r);
init_task_work(newwork, key_change_session_keyring, cred); init_task_work(&newwork->twork, key_change_session_keyring);
newwork->cred = cred;
me = current; me = current;
rcu_read_lock(); rcu_read_lock();
...@@ -1527,18 +1529,18 @@ long keyctl_session_to_parent(void) ...@@ -1527,18 +1529,18 @@ long keyctl_session_to_parent(void)
/* the replacement session keyring is applied just prior to userspace /* the replacement session keyring is applied just prior to userspace
* restarting */ * restarting */
ret = task_work_add(parent, newwork, true); ret = task_work_add(parent, &newwork->twork, true);
if (!ret) if (!ret)
newwork = NULL; newwork = NULL;
unlock: unlock:
write_unlock_irq(&tasklist_lock); write_unlock_irq(&tasklist_lock);
rcu_read_unlock(); rcu_read_unlock();
if (oldwork) { if (oldwork) {
put_cred(oldwork->data); put_cred(container_of(oldwork, struct kludge, twork)->cred);
kfree(oldwork); kfree(oldwork);
} }
if (newwork) { if (newwork) {
put_cred(newwork->data); put_cred(newwork->cred);
kfree(newwork); kfree(newwork);
} }
return ret; return ret;
......
...@@ -837,9 +837,10 @@ long join_session_keyring(const char *name) ...@@ -837,9 +837,10 @@ long join_session_keyring(const char *name)
void key_change_session_keyring(struct task_work *twork) void key_change_session_keyring(struct task_work *twork)
{ {
const struct cred *old = current_cred(); const struct cred *old = current_cred();
struct cred *new = twork->data; struct kludge *p = container_of(twork, struct kludge, twork);
struct cred *new = p->cred;
kfree(twork); kfree(p);
if (unlikely(current->flags & PF_EXITING)) { if (unlikely(current->flags & PF_EXITING)) {
put_cred(new); put_cred(new);
return; return;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment