Commit f48fc4d3 authored by Jens Axboe's avatar Jens Axboe

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: default avatarJens Axboe <jens.axboe@oracle.com>
parent 32231638
...@@ -187,59 +187,12 @@ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes, ...@@ -187,59 +187,12 @@ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes,
static struct dentry *blk_tree_root; static struct dentry *blk_tree_root;
static DEFINE_MUTEX(blk_tree_mutex); static DEFINE_MUTEX(blk_tree_mutex);
static unsigned int root_users;
static inline void blk_remove_root(void)
{
if (blk_tree_root) {
debugfs_remove(blk_tree_root);
blk_tree_root = NULL;
}
}
static void blk_remove_tree(struct dentry *dir)
{
mutex_lock(&blk_tree_mutex);
debugfs_remove(dir);
if (--root_users == 0)
blk_remove_root();
mutex_unlock(&blk_tree_mutex);
}
static struct dentry *blk_create_tree(const char *blk_name)
{
struct dentry *dir = NULL;
int created = 0;
mutex_lock(&blk_tree_mutex);
if (!blk_tree_root) {
blk_tree_root = debugfs_create_dir("block", NULL);
if (!blk_tree_root)
goto err;
created = 1;
}
dir = debugfs_create_dir(blk_name, blk_tree_root);
if (dir)
root_users++;
else {
/* Delete root only if we created it */
if (created)
blk_remove_root();
}
err:
mutex_unlock(&blk_tree_mutex);
return dir;
}
static void blk_trace_cleanup(struct blk_trace *bt) static void blk_trace_cleanup(struct blk_trace *bt)
{ {
relay_close(bt->rchan);
debugfs_remove(bt->msg_file); debugfs_remove(bt->msg_file);
debugfs_remove(bt->dropped_file); debugfs_remove(bt->dropped_file);
blk_remove_tree(bt->dir); relay_close(bt->rchan);
free_percpu(bt->sequence); free_percpu(bt->sequence);
free_percpu(bt->msg_data); free_percpu(bt->msg_data);
kfree(bt); kfree(bt);
...@@ -346,7 +299,18 @@ static int blk_subbuf_start_callback(struct rchan_buf *buf, void *subbuf, ...@@ -346,7 +299,18 @@ static int blk_subbuf_start_callback(struct rchan_buf *buf, void *subbuf,
static int blk_remove_buf_file_callback(struct dentry *dentry) static int blk_remove_buf_file_callback(struct dentry *dentry)
{ {
struct dentry *parent = dentry->d_parent;
debugfs_remove(dentry); debugfs_remove(dentry);
/*
* this will fail for all but the last file, but that is ok. what we
* care about is the top level buts->name directory going away, when
* the last trace file is gone. Then we don't have to rmdir() that
* manually on trace stop, so it nicely solves the issue with
* force killing of running traces.
*/
debugfs_remove(parent);
return 0; return 0;
} }
...@@ -404,7 +368,15 @@ int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev, ...@@ -404,7 +368,15 @@ int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
goto err; goto err;
ret = -ENOENT; ret = -ENOENT;
dir = blk_create_tree(buts->name);
if (!blk_tree_root) {
blk_tree_root = debugfs_create_dir("block", NULL);
if (!blk_tree_root)
return -ENOMEM;
}
dir = debugfs_create_dir(buts->name, blk_tree_root);
if (!dir) if (!dir)
goto err; goto err;
...@@ -458,8 +430,6 @@ int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev, ...@@ -458,8 +430,6 @@ int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
atomic_dec(&blk_probes_ref); atomic_dec(&blk_probes_ref);
mutex_unlock(&blk_probe_mutex); mutex_unlock(&blk_probe_mutex);
err: err:
if (dir)
blk_remove_tree(dir);
if (bt) { if (bt) {
if (bt->msg_file) if (bt->msg_file)
debugfs_remove(bt->msg_file); debugfs_remove(bt->msg_file);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment