revert-mm-fix-blkdev-size-calculation-in-generic_write_checks
[linux-2.6/linux-trees-mm.git] / fs / reiser4 / ktxnmgrd.c
blob75567b92545a58ac9ed348e9acb1ddf79ace075d
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, TASK_INTERRUPTIBLE);
82 if (kthread_should_stop()) {
83 done = 1;
84 } else
85 schedule_timeout(ctx->timeout);
86 finish_wait(&ctx->wait, &__wait);
88 if (done)
89 break;
90 set_comm("run");
91 spin_lock(&ctx->guard);
93 * wait timed out or ktxnmgrd was woken up by explicit request
94 * to commit something. Scan list of atoms in txnmgr and look
95 * for too old atoms.
97 do {
98 ctx->rescan = 0;
99 scan_mgr(super);
100 spin_lock(&ctx->guard);
101 if (ctx->rescan) {
103 * the list could be modified while ctx
104 * spinlock was released, we have to repeat
105 * scanning from the beginning
107 break;
109 } while (ctx->rescan);
110 spin_unlock(&ctx->guard);
112 return 0;
115 #undef set_comm
118 * reiser4_init_ktxnmgrd - initialize ktxnmgrd context and start kernel daemon
119 * @super: pointer to super block
121 * Allocates and initializes ktxnmgrd_context, attaches it to transaction
122 * manager. Starts kernel txnmgr daemon. This is called on mount.
124 int reiser4_init_ktxnmgrd(struct super_block *super)
126 txn_mgr *mgr;
127 ktxnmgrd_context *ctx;
129 mgr = &get_super_private(super)->tmgr;
131 assert("zam-1014", mgr->daemon == NULL);
133 ctx = kzalloc(sizeof(ktxnmgrd_context), reiser4_ctx_gfp_mask_get());
134 if (!ctx)
135 return RETERR(-ENOMEM);
137 assert("nikita-2442", ctx != NULL);
139 init_waitqueue_head(&ctx->wait);
141 /*kcond_init(&ctx->startup);*/
142 spin_lock_init(&ctx->guard);
143 ctx->timeout = REISER4_TXNMGR_TIMEOUT;
144 ctx->rescan = 1;
145 mgr->daemon = ctx;
147 ctx->tsk = kthread_run(ktxnmgrd, super, "ktxnmgrd");
148 if (IS_ERR(ctx->tsk)) {
149 int ret = PTR_ERR(ctx->tsk);
150 mgr->daemon = NULL;
151 kfree(ctx);
152 return RETERR(ret);
154 return 0;
157 void ktxnmgrd_kick(txn_mgr *mgr)
159 assert("nikita-3234", mgr != NULL);
160 assert("nikita-3235", mgr->daemon != NULL);
161 wake_up(&mgr->daemon->wait);
164 int is_current_ktxnmgrd(void)
166 return (get_current_super_private()->tmgr.daemon->tsk == current);
170 * scan_mgr - commit atoms which are to be committed
171 * @super: super block to commit atoms of
173 * Commits old atoms.
175 static int scan_mgr(struct super_block *super)
177 int ret;
178 reiser4_context ctx;
180 init_stack_context(&ctx, super);
182 ret = commit_some_atoms(&get_super_private(super)->tmgr);
184 reiser4_exit_context(&ctx);
185 return ret;
189 * reiser4_done_ktxnmgrd - stop kernel thread and frees ktxnmgrd context
190 * @mgr:
192 * This is called on umount. Stops ktxnmgrd and free t
194 void reiser4_done_ktxnmgrd(struct super_block *super)
196 txn_mgr *mgr;
198 mgr = &get_super_private(super)->tmgr;
199 assert("zam-1012", mgr->daemon != NULL);
201 kthread_stop(mgr->daemon->tsk);
202 kfree(mgr->daemon);
203 mgr->daemon = NULL;
207 * Local variables:
208 * c-indentation-style: "K&R"
209 * mode-name: "LC"
210 * c-basic-offset: 8
211 * tab-width: 8
212 * fill-column: 120
213 * End: