aboutsummaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
authorJens Axboe <jens.axboe@oracle.com>2009-01-05 04:17:25 -0500
committerJens Axboe <jens.axboe@oracle.com>2009-01-30 06:34:36 -0500
commitf48fc4d32e24c0b6a18aad30305d819bcc68c049 (patch)
treed993ccadfe87a0c481fba7e697107bb5cc701b4a /block
parent322316385dde5cd879e682bcb598c56d0659fb60 (diff)
block: get rid of the manual directory counting in blktrace
It can result in a stuck blktrace system, if --kill is used. Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'block')
-rw-r--r--block/blktrace.c72
1 files changed, 21 insertions, 51 deletions
diff --git a/block/blktrace.c b/block/blktrace.c
index b0a2cae886db..39cc3bfe56e4 100644
--- a/block/blktrace.c
+++ b/block/blktrace.c
@@ -187,59 +187,12 @@ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes,
187 187
188static struct dentry *blk_tree_root; 188static struct dentry *blk_tree_root;
189static DEFINE_MUTEX(blk_tree_mutex); 189static DEFINE_MUTEX(blk_tree_mutex);
190static unsigned int root_users;
191
192static inline void blk_remove_root(void)
193{
194 if (blk_tree_root) {
195 debugfs_remove(blk_tree_root);
196 blk_tree_root = NULL;
197 }
198}
199
200static void blk_remove_tree(struct dentry *dir)
201{
202 mutex_lock(&blk_tree_mutex);
203 debugfs_remove(dir);
204 if (--root_users == 0)
205 blk_remove_root();
206 mutex_unlock(&blk_tree_mutex);
207}
208
209static struct dentry *blk_create_tree(const char *blk_name)
210{
211 struct dentry *dir = NULL;
212 int created = 0;
213
214 mutex_lock(&blk_tree_mutex);
215
216 if (!blk_tree_root) {
217 blk_tree_root = debugfs_create_dir("block", NULL);
218 if (!blk_tree_root)
219 goto err;
220 created = 1;
221 }
222
223 dir = debugfs_create_dir(blk_name, blk_tree_root);
224 if (dir)
225 root_users++;
226 else {
227 /* Delete root only if we created it */
228 if (created)
229 blk_remove_root();
230 }
231
232err:
233 mutex_unlock(&blk_tree_mutex);
234 return dir;
235}
236 190
237static void blk_trace_cleanup(struct blk_trace *bt) 191static void blk_trace_cleanup(struct blk_trace *bt)
238{ 192{
239 relay_close(bt->rchan);
240 debugfs_remove(bt->msg_file); 193 debugfs_remove(bt->msg_file);
241 debugfs_remove(bt->dropped_file); 194 debugfs_remove(bt->dropped_file);
242 blk_remove_tree(bt->dir); 195 relay_close(bt->rchan);
243 free_percpu(bt->sequence); 196 free_percpu(bt->sequence);
244 free_percpu(bt->msg_data); 197 free_percpu(bt->msg_data);
245 kfree(bt); 198 kfree(bt);
@@ -346,7 +299,18 @@ static int blk_subbuf_start_callback(struct rchan_buf *buf, void *subbuf,
346 299
347static int blk_remove_buf_file_callback(struct dentry *dentry) 300static int blk_remove_buf_file_callback(struct dentry *dentry)
348{ 301{
302 struct dentry *parent = dentry->d_parent;
349 debugfs_remove(dentry); 303 debugfs_remove(dentry);
304
305 /*
306 * this will fail for all but the last file, but that is ok. what we
307 * care about is the top level buts->name directory going away, when
308 * the last trace file is gone. Then we don't have to rmdir() that
309 * manually on trace stop, so it nicely solves the issue with
310 * force killing of running traces.
311 */
312
313 debugfs_remove(parent);
350 return 0; 314 return 0;
351} 315}
352 316
@@ -404,7 +368,15 @@ int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
404 goto err; 368 goto err;
405 369
406 ret = -ENOENT; 370 ret = -ENOENT;
407 dir = blk_create_tree(buts->name); 371
372 if (!blk_tree_root) {
373 blk_tree_root = debugfs_create_dir("block", NULL);
374 if (!blk_tree_root)
375 return -ENOMEM;
376 }
377
378 dir = debugfs_create_dir(buts->name, blk_tree_root);
379
408 if (!dir) 380 if (!dir)
409 goto err; 381 goto err;
410 382
@@ -458,8 +430,6 @@ probe_err:
458 atomic_dec(&blk_probes_ref); 430 atomic_dec(&blk_probes_ref);
459 mutex_unlock(&blk_probe_mutex); 431 mutex_unlock(&blk_probe_mutex);
460err: 432err:
461 if (dir)
462 blk_remove_tree(dir);
463 if (bt) { 433 if (bt) {
464 if (bt->msg_file) 434 if (bt->msg_file)
465 debugfs_remove(bt->msg_file); 435 debugfs_remove(bt->msg_file);