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
, TASK_INTERRUPTIBLE
);
82 if (kthread_should_stop()) {
85 schedule_timeout(ctx
->timeout
);
86 finish_wait(&ctx
->wait
, &__wait
);
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
100 spin_lock(&ctx
->guard
);
103 * the list could be modified while ctx
104 * spinlock was released, we have to repeat
105 * scanning from the beginning
109 } while (ctx
->rescan
);
110 spin_unlock(&ctx
->guard
);
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
)
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());
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
;
147 ctx
->tsk
= kthread_run(ktxnmgrd
, super
, "ktxnmgrd");
148 if (IS_ERR(ctx
->tsk
)) {
149 int ret
= PTR_ERR(ctx
->tsk
);
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
175 static int scan_mgr(struct super_block
*super
)
180 init_stack_context(&ctx
, super
);
182 ret
= commit_some_atoms(&get_super_private(super
)->tmgr
);
184 reiser4_exit_context(&ctx
);
189 * reiser4_done_ktxnmgrd - stop kernel thread and frees ktxnmgrd context
192 * This is called on umount. Stops ktxnmgrd and free t
194 void reiser4_done_ktxnmgrd(struct super_block
*super
)
198 mgr
= &get_super_private(super
)->tmgr
;
199 assert("zam-1012", mgr
->daemon
!= NULL
);
201 kthread_stop(mgr
->daemon
->tsk
);
208 * c-indentation-style: "K&R"