1 /* Copyright 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */
2 /* Transaction manager daemon. */
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.
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
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))
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
;
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
;
81 prepare_to_wait(&ctx
->wait
, &__wait
,
83 if (kthread_should_stop())
86 schedule_timeout(ctx
->timeout
);
87 finish_wait(&ctx
->wait
, &__wait
);
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
101 spin_lock(&ctx
->guard
);
104 * the list could be modified while ctx
105 * spinlock was released, we have to repeat
106 * scanning from the beginning
110 } while (ctx
->rescan
);
111 spin_unlock(&ctx
->guard
);
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
)
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());
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
;
148 ctx
->tsk
= kthread_run(ktxnmgrd
, super
, "ktxnmgrd");
149 if (IS_ERR(ctx
->tsk
)) {
150 int ret
= PTR_ERR(ctx
->tsk
);
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
176 static int scan_mgr(struct super_block
*super
)
181 init_stack_context(&ctx
, super
);
183 ret
= commit_some_atoms(&get_super_private(super
)->tmgr
);
185 reiser4_exit_context(&ctx
);
190 * reiser4_done_ktxnmgrd - stop kernel thread and frees ktxnmgrd context
193 * This is called on umount. Stops ktxnmgrd and free t
195 void reiser4_done_ktxnmgrd(struct super_block
*super
)
199 mgr
= &get_super_private(super
)->tmgr
;
200 assert("zam-1012", mgr
->daemon
!= NULL
);
202 kthread_stop(mgr
->daemon
->tsk
);
209 * c-indentation-style: "K&R"