Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
fs
jffs2
background.c
Go to the documentation of this file.
1
/*
2
* JFFS2 -- Journalling Flash File System, Version 2.
3
*
4
* Copyright © 2001-2007 Red Hat, Inc.
5
* Copyright © 2004-2010 David Woodhouse <
[email protected]
>
6
*
7
* Created by David Woodhouse <
[email protected]
>
8
*
9
* For licensing information, see the file 'LICENCE' in this directory.
10
*
11
*/
12
13
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
14
15
#include <linux/kernel.h>
16
#include <
linux/jffs2.h
>
17
#include <
linux/mtd/mtd.h
>
18
#include <
linux/completion.h
>
19
#include <linux/sched.h>
20
#include <
linux/freezer.h
>
21
#include <
linux/kthread.h
>
22
#include "
nodelist.h
"
23
24
25
static
int
jffs2_garbage_collect_thread(
void
*);
26
27
void
jffs2_garbage_collect_trigger
(
struct
jffs2_sb_info
*
c
)
28
{
29
assert_spin_locked
(&c->
erase_completion_lock
);
30
if
(c->
gc_task
&&
jffs2_thread_should_wake
(c))
31
send_sig
(
SIGHUP
, c->
gc_task
, 1);
32
}
33
34
/* This must only ever be called when no GC thread is currently running */
35
int
jffs2_start_garbage_collect_thread
(
struct
jffs2_sb_info
*
c
)
36
{
37
struct
task_struct
*tsk;
38
int
ret
= 0;
39
40
BUG_ON
(c->
gc_task
);
41
42
init_completion(&c->
gc_thread_start
);
43
init_completion(&c->
gc_thread_exit
);
44
45
tsk =
kthread_run
(jffs2_garbage_collect_thread, c,
"jffs2_gcd_mtd%d"
, c->
mtd
->index);
46
if
(IS_ERR(tsk)) {
47
pr_warn
(
"fork failed for JFFS2 garbage collect thread: %ld\n"
,
48
-PTR_ERR(tsk));
49
complete
(&c->
gc_thread_exit
);
50
ret = PTR_ERR(tsk);
51
}
else
{
52
/* Wait for it... */
53
jffs2_dbg
(1,
"Garbage collect thread is pid %d\n"
, tsk->
pid
);
54
wait_for_completion
(&c->
gc_thread_start
);
55
ret = tsk->
pid
;
56
}
57
58
return
ret
;
59
}
60
61
void
jffs2_stop_garbage_collect_thread
(
struct
jffs2_sb_info
*
c
)
62
{
63
int
wait
= 0;
64
spin_lock(&c->
erase_completion_lock
);
65
if
(c->
gc_task
) {
66
jffs2_dbg
(1,
"Killing GC task %d\n"
, c->
gc_task
->pid);
67
send_sig
(
SIGKILL
, c->
gc_task
, 1);
68
wait = 1;
69
}
70
spin_unlock(&c->
erase_completion_lock
);
71
if
(wait)
72
wait_for_completion
(&c->
gc_thread_exit
);
73
}
74
75
static
int
jffs2_garbage_collect_thread(
void
*_c)
76
{
77
struct
jffs2_sb_info
*
c
= _c;
78
79
allow_signal
(
SIGKILL
);
80
allow_signal
(
SIGSTOP
);
81
allow_signal
(
SIGCONT
);
82
83
c->
gc_task
=
current
;
84
complete
(&c->
gc_thread_start
);
85
86
set_user_nice
(
current
, 10);
87
88
set_freezable
();
89
for
(;;) {
90
allow_signal
(
SIGHUP
);
91
again:
92
spin_lock(&c->
erase_completion_lock
);
93
if
(!
jffs2_thread_should_wake
(c)) {
94
set_current_state
(
TASK_INTERRUPTIBLE
);
95
spin_unlock(&c->
erase_completion_lock
);
96
jffs2_dbg
(1,
"%s(): sleeping...\n"
, __func__);
97
schedule
();
98
}
else
99
spin_unlock(&c->
erase_completion_lock
);
100
101
102
/* Problem - immediately after bootup, the GCD spends a lot
103
* of time in places like jffs2_kill_fragtree(); so much so
104
* that userspace processes (like gdm and X) are starved
105
* despite plenty of cond_resched()s and renicing. Yield()
106
* doesn't help, either (presumably because userspace and GCD
107
* are generally competing for a higher latency resource -
108
* disk).
109
* This forces the GCD to slow the hell down. Pulling an
110
* inode in with read_inode() is much preferable to having
111
* the GC thread get there first. */
112
schedule_timeout_interruptible
(
msecs_to_jiffies
(50));
113
114
if
(
kthread_should_stop
()) {
115
jffs2_dbg
(1,
"%s(): kthread_stop() called\n"
, __func__);
116
goto
die
;
117
}
118
119
/* Put_super will send a SIGKILL and then wait on the sem.
120
*/
121
while
(signal_pending(
current
) || freezing(
current
)) {
122
siginfo_t
info
;
123
unsigned
long
signr;
124
125
if
(try_to_freeze())
126
goto
again;
127
128
signr = dequeue_signal_lock(
current
, &
current
->blocked, &info);
129
130
switch
(signr) {
131
case
SIGSTOP
:
132
jffs2_dbg
(1,
"%s(): SIGSTOP received\n"
,
133
__func__);
134
set_current_state
(
TASK_STOPPED
);
135
schedule
();
136
break
;
137
138
case
SIGKILL
:
139
jffs2_dbg
(1,
"%s(): SIGKILL received\n"
,
140
__func__);
141
goto
die
;
142
143
case
SIGHUP
:
144
jffs2_dbg
(1,
"%s(): SIGHUP received\n"
,
145
__func__);
146
break
;
147
default
:
148
jffs2_dbg
(1,
"%s(): signal %ld received\n"
,
149
__func__, signr);
150
}
151
}
152
/* We don't want SIGHUP to interrupt us. STOP and KILL are OK though. */
153
disallow_signal
(
SIGHUP
);
154
155
jffs2_dbg
(1,
"%s(): pass\n"
, __func__);
156
if
(
jffs2_garbage_collect_pass
(c) == -
ENOSPC
) {
157
pr_notice
(
"No space for garbage collection. Aborting GC thread\n"
);
158
goto
die
;
159
}
160
}
161
die
:
162
spin_lock(&c->
erase_completion_lock
);
163
c->
gc_task
=
NULL
;
164
spin_unlock(&c->
erase_completion_lock
);
165
complete_and_exit
(&c->
gc_thread_exit
, 0);
166
}
Generated on Thu Jan 10 2013 14:47:38 for Linux Kernel by
1.8.2