]>
Commit | Line | Data |
---|---|---|
2cb7cef9 BS |
1 | From: Jens Axboe <jens.axboe@oracle.com> |
2 | Date: Mon Jan 5 10:17:25 2009 +0100 | |
3 | Subject: block: get rid of the manual directory counting in blktrace | |
4 | References: bnc#475149 | |
5 | ||
6 | It can result in a stuck blktrace system, if --kill is used. | |
7 | ||
8 | Signed-off-by: Jens Axboe <jens.axboe@oracle.com> | |
9 | ||
10 | Acked-by: Jan Blunck <jblunck@suse.de> | |
11 | --- | |
12 | block/blktrace.c | 72 ++++++++++++++++--------------------------------------- | |
13 | 1 file changed, 21 insertions(+), 51 deletions(-) | |
14 | ||
15 | Index: b/block/blktrace.c | |
16 | =================================================================== | |
17 | --- a/block/blktrace.c | |
18 | +++ b/block/blktrace.c | |
19 | @@ -181,59 +181,12 @@ EXPORT_SYMBOL_GPL(__blk_add_trace); | |
20 | ||
21 | static struct dentry *blk_tree_root; | |
22 | static DEFINE_MUTEX(blk_tree_mutex); | |
23 | -static unsigned int root_users; | |
24 | - | |
25 | -static inline void blk_remove_root(void) | |
26 | -{ | |
27 | - if (blk_tree_root) { | |
28 | - debugfs_remove(blk_tree_root); | |
29 | - blk_tree_root = NULL; | |
30 | - } | |
31 | -} | |
32 | - | |
33 | -static void blk_remove_tree(struct dentry *dir) | |
34 | -{ | |
35 | - mutex_lock(&blk_tree_mutex); | |
36 | - debugfs_remove(dir); | |
37 | - if (--root_users == 0) | |
38 | - blk_remove_root(); | |
39 | - mutex_unlock(&blk_tree_mutex); | |
40 | -} | |
41 | - | |
42 | -static struct dentry *blk_create_tree(const char *blk_name) | |
43 | -{ | |
44 | - struct dentry *dir = NULL; | |
45 | - int created = 0; | |
46 | - | |
47 | - mutex_lock(&blk_tree_mutex); | |
48 | - | |
49 | - if (!blk_tree_root) { | |
50 | - blk_tree_root = debugfs_create_dir("block", NULL); | |
51 | - if (!blk_tree_root) | |
52 | - goto err; | |
53 | - created = 1; | |
54 | - } | |
55 | - | |
56 | - dir = debugfs_create_dir(blk_name, blk_tree_root); | |
57 | - if (dir) | |
58 | - root_users++; | |
59 | - else { | |
60 | - /* Delete root only if we created it */ | |
61 | - if (created) | |
62 | - blk_remove_root(); | |
63 | - } | |
64 | - | |
65 | -err: | |
66 | - mutex_unlock(&blk_tree_mutex); | |
67 | - return dir; | |
68 | -} | |
69 | ||
70 | static void blk_trace_cleanup(struct blk_trace *bt) | |
71 | { | |
72 | - relay_close(bt->rchan); | |
73 | debugfs_remove(bt->msg_file); | |
74 | debugfs_remove(bt->dropped_file); | |
75 | - blk_remove_tree(bt->dir); | |
76 | + relay_close(bt->rchan); | |
77 | free_percpu(bt->sequence); | |
78 | free_percpu(bt->msg_data); | |
79 | kfree(bt); | |
80 | @@ -336,7 +289,18 @@ static int blk_subbuf_start_callback(str | |
81 | ||
82 | static int blk_remove_buf_file_callback(struct dentry *dentry) | |
83 | { | |
84 | + struct dentry *parent = dentry->d_parent; | |
85 | debugfs_remove(dentry); | |
86 | + | |
87 | + /* | |
88 | + * this will fail for all but the last file, but that is ok. what we | |
89 | + * care about is the top level buts->name directory going away, when | |
90 | + * the last trace file is gone. Then we don't have to rmdir() that | |
91 | + * manually on trace stop, so it nicely solves the issue with | |
92 | + * force killing of running traces. | |
93 | + */ | |
94 | + | |
95 | + debugfs_remove(parent); | |
96 | return 0; | |
97 | } | |
98 | ||
99 | @@ -393,7 +357,15 @@ int do_blk_trace_setup(struct request_qu | |
100 | goto err; | |
101 | ||
102 | ret = -ENOENT; | |
103 | - dir = blk_create_tree(buts->name); | |
104 | + | |
105 | + if (!blk_tree_root) { | |
106 | + blk_tree_root = debugfs_create_dir("block", NULL); | |
107 | + if (!blk_tree_root) | |
108 | + return -ENOMEM; | |
109 | + } | |
110 | + | |
111 | + dir = debugfs_create_dir(buts->name, blk_tree_root); | |
112 | + | |
113 | if (!dir) | |
114 | goto err; | |
115 | ||
116 | @@ -436,8 +408,6 @@ int do_blk_trace_setup(struct request_qu | |
117 | ||
118 | return 0; | |
119 | err: | |
120 | - if (dir) | |
121 | - blk_remove_tree(dir); | |
122 | if (bt) { | |
123 | if (bt->msg_file) | |
124 | debugfs_remove(bt->msg_file); |