mm-only debug patch...
[mmotm.git] / fs / reiser4 / ktxnmgrd.c
blobb36215b3db438e6cd8266befd60384cdd3e0daa4
1 /* Copyright 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */
2 /* Transaction manager daemon. */
4 /*
5 * ktxnmgrd is a kernel daemon responsible for committing transactions. It is
6 * needed/important for the following reasons:
8 * 1. in reiser4 atom is not committed immediately when last transaction
9 * handle closes, unless atom is either too old or too large (see
10 * atom_should_commit()). This is done to avoid committing too frequently.
11 * because:
13 * 2. sometimes we don't want to commit atom when closing last transaction
14 * handle even if it is old and fat enough. For example, because we are at
15 * this point under directory semaphore, and committing would stall all
16 * accesses to this directory.
18 * ktxnmgrd binds its time sleeping on condition variable. When is awakes
19 * either due to (tunable) timeout or because it was explicitly woken up by
20 * call to ktxnmgrd_kick(), it scans list of all atoms and commits ones
21 * eligible.
25 #include "debug.h"
26 #include "txnmgr.h"
27 #include "tree.h"
28 #include "ktxnmgrd.h"
29 #include "super.h"
30 #include "reiser4.h"
32 #include <linux/sched.h> /* for struct task_struct */
33 #include <linux/wait.h>
34 #include <linux/suspend.h>
35 #include <linux/kernel.h>
36 #include <linux/writeback.h>
37 #include <linux/kthread.h>
38 #include <linux/freezer.h>
40 static int scan_mgr(struct super_block *);
43 * change current->comm so that ps, top, and friends will see changed
44 * state. This serves no useful purpose whatsoever, but also costs nothing. May
45 * be it will make lonely system administrator feeling less alone at 3 A.M.
47 #define set_comm(state) \
48 snprintf(current->comm, sizeof(current->comm), \
49 "%s:%s:%s", __FUNCTION__, (super)->s_id, (state))
51 /**
52 * ktxnmgrd - kernel txnmgr daemon
53 * @arg: pointer to super block
55 * The background transaction manager daemon, started as a kernel thread during
56 * reiser4 initialization.
58 static int ktxnmgrd(void *arg)
60 struct super_block *super;
61 ktxnmgrd_context *ctx;
62 txn_mgr *mgr;
63 int done = 0;
65 super = arg;
66 mgr = &get_super_private(super)->tmgr;
69 * do_fork() just copies task_struct into the new thread. ->fs_context
70 * shouldn't be copied of course. This shouldn't be a problem for the
71 * rest of the code though.
73 current->journal_info = NULL;
74 ctx = mgr->daemon;
75 while (1) {
76 try_to_freeze();
77 set_comm("wait");
79 DEFINE_WAIT(__wait);
81 prepare_to_wait(&ctx->wait, &__wait,
82 TASK_INTERRUPTIBLE);
83 if (kthread_should_stop())
84 done = 1;
85 else
86 schedule_timeout(ctx->timeout);
87 finish_wait(&ctx->wait, &__wait);
89 if (done)
90 break;
91 set_comm("run");
92 spin_lock(&ctx->guard);
94 * wait timed out or ktxnmgrd was woken up by explicit request
95 * to commit something. Scan list of atoms in txnmgr and look
96 * for too old atoms.
98 do {
99 ctx->rescan = 0;
100 scan_mgr(super);
101 spin_lock(&ctx->guard);
102 if (ctx->rescan) {
104 * the list could be modified while ctx
105 * spinlock was released, we have to repeat
106 * scanning from the beginning
108 break;
110 } while (ctx->rescan);
111 spin_unlock(&ctx->guard);
113 return 0;
116 #undef set_comm
119 * reiser4_init_ktxnmgrd - initialize ktxnmgrd context and start kernel daemon
120 * @super: pointer to super block
122 * Allocates and initializes ktxnmgrd_context, attaches it to transaction
123 * manager. Starts kernel txnmgr daemon. This is called on mount.
125 int reiser4_init_ktxnmgrd(struct super_block *super)
127 txn_mgr *mgr;
128 ktxnmgrd_context *ctx;
130 mgr = &get_super_private(super)->tmgr;
132 assert("zam-1014", mgr->daemon == NULL);
134 ctx = kzalloc(sizeof(ktxnmgrd_context), reiser4_ctx_gfp_mask_get());
135 if (!ctx)
136 return RETERR(-ENOMEM);
138 assert("nikita-2442", ctx != NULL);
140 init_waitqueue_head(&ctx->wait);
142 /*kcond_init(&ctx->startup);*/
143 spin_lock_init(&ctx->guard);
144 ctx->timeout = REISER4_TXNMGR_TIMEOUT;
145 ctx->rescan = 1;
146 mgr->daemon = ctx;
148 ctx->tsk = kthread_run(ktxnmgrd, super, "ktxnmgrd");
149 if (IS_ERR(ctx->tsk)) {
150 int ret = PTR_ERR(ctx->tsk);
151 mgr->daemon = NULL;
152 kfree(ctx);
153 return RETERR(ret);
155 return 0;
158 void ktxnmgrd_kick(txn_mgr *mgr)
160 assert("nikita-3234", mgr != NULL);
161 assert("nikita-3235", mgr->daemon != NULL);
162 wake_up(&mgr->daemon->wait);
165 int is_current_ktxnmgrd(void)
167 return (get_current_super_private()->tmgr.daemon->tsk == current);
171 * scan_mgr - commit atoms which are to be committed
172 * @super: super block to commit atoms of
174 * Commits old atoms.
176 static int scan_mgr(struct super_block *super)
178 int ret;
179 reiser4_context ctx;
181 init_stack_context(&ctx, super);
183 ret = commit_some_atoms(&get_super_private(super)->tmgr);
185 reiser4_exit_context(&ctx);
186 return ret;
190 * reiser4_done_ktxnmgrd - stop kernel thread and frees ktxnmgrd context
191 * @mgr:
193 * This is called on umount. Stops ktxnmgrd and free t
195 void reiser4_done_ktxnmgrd(struct super_block *super)
197 txn_mgr *mgr;
199 mgr = &get_super_private(super)->tmgr;
200 assert("zam-1012", mgr->daemon != NULL);
202 kthread_stop(mgr->daemon->tsk);
203 kfree(mgr->daemon);
204 mgr->daemon = NULL;
208 * Local variables:
209 * c-indentation-style: "K&R"
210 * mode-name: "LC"
211 * c-basic-offset: 8
212 * tab-width: 8
213 * fill-column: 120
214 * End: