diff options
Diffstat (limited to 'kernel/trace')
| -rw-r--r-- | kernel/trace/trace.c | 75 |
1 files changed, 5 insertions, 70 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index b4aa936509d2..3c8913bac204 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
| @@ -6292,7 +6292,7 @@ static void free_trace_buffers(struct trace_array *tr) | |||
| 6292 | #endif | 6292 | #endif |
| 6293 | } | 6293 | } |
| 6294 | 6294 | ||
| 6295 | static int new_instance_create(const char *name) | 6295 | static int instance_mkdir(const char *name) |
| 6296 | { | 6296 | { |
| 6297 | struct trace_array *tr; | 6297 | struct trace_array *tr; |
| 6298 | int ret; | 6298 | int ret; |
| @@ -6362,7 +6362,7 @@ static int new_instance_create(const char *name) | |||
| 6362 | 6362 | ||
| 6363 | } | 6363 | } |
| 6364 | 6364 | ||
| 6365 | static int instance_delete(const char *name) | 6365 | static int instance_rmdir(const char *name) |
| 6366 | { | 6366 | { |
| 6367 | struct trace_array *tr; | 6367 | struct trace_array *tr; |
| 6368 | int found = 0; | 6368 | int found = 0; |
| @@ -6403,78 +6403,13 @@ static int instance_delete(const char *name) | |||
| 6403 | return ret; | 6403 | return ret; |
| 6404 | } | 6404 | } |
| 6405 | 6405 | ||
| 6406 | static int instance_mkdir (struct inode *inode, struct dentry *dentry, umode_t mode) | ||
| 6407 | { | ||
| 6408 | struct dentry *parent; | ||
| 6409 | int ret; | ||
| 6410 | |||
| 6411 | /* Paranoid: Make sure the parent is the "instances" directory */ | ||
| 6412 | parent = hlist_entry(inode->i_dentry.first, struct dentry, d_u.d_alias); | ||
| 6413 | if (WARN_ON_ONCE(parent != trace_instance_dir)) | ||
| 6414 | return -ENOENT; | ||
| 6415 | |||
| 6416 | /* | ||
| 6417 | * The inode mutex is locked, but tracefs_create_dir() will also | ||
| 6418 | * take the mutex. As the instances directory can not be destroyed | ||
| 6419 | * or changed in any other way, it is safe to unlock it, and | ||
| 6420 | * let the dentry try. If two users try to make the same dir at | ||
| 6421 | * the same time, then the new_instance_create() will determine the | ||
| 6422 | * winner. | ||
| 6423 | */ | ||
| 6424 | mutex_unlock(&inode->i_mutex); | ||
| 6425 | |||
| 6426 | ret = new_instance_create(dentry->d_iname); | ||
| 6427 | |||
| 6428 | mutex_lock(&inode->i_mutex); | ||
| 6429 | |||
| 6430 | return ret; | ||
| 6431 | } | ||
| 6432 | |||
| 6433 | static int instance_rmdir(struct inode *inode, struct dentry *dentry) | ||
| 6434 | { | ||
| 6435 | struct dentry *parent; | ||
| 6436 | int ret; | ||
| 6437 | |||
| 6438 | /* Paranoid: Make sure the parent is the "instances" directory */ | ||
| 6439 | parent = hlist_entry(inode->i_dentry.first, struct dentry, d_u.d_alias); | ||
| 6440 | if (WARN_ON_ONCE(parent != trace_instance_dir)) | ||
| 6441 | return -ENOENT; | ||
| 6442 | |||
| 6443 | /* The caller did a dget() on dentry */ | ||
| 6444 | mutex_unlock(&dentry->d_inode->i_mutex); | ||
| 6445 | |||
| 6446 | /* | ||
| 6447 | * The inode mutex is locked, but tracefs_create_dir() will also | ||
| 6448 | * take the mutex. As the instances directory can not be destroyed | ||
| 6449 | * or changed in any other way, it is safe to unlock it, and | ||
| 6450 | * let the dentry try. If two users try to make the same dir at | ||
| 6451 | * the same time, then the instance_delete() will determine the | ||
| 6452 | * winner. | ||
| 6453 | */ | ||
| 6454 | mutex_unlock(&inode->i_mutex); | ||
| 6455 | |||
| 6456 | ret = instance_delete(dentry->d_iname); | ||
| 6457 | |||
| 6458 | mutex_lock_nested(&inode->i_mutex, I_MUTEX_PARENT); | ||
| 6459 | mutex_lock(&dentry->d_inode->i_mutex); | ||
| 6460 | |||
| 6461 | return ret; | ||
| 6462 | } | ||
| 6463 | |||
| 6464 | static const struct inode_operations instance_dir_inode_operations = { | ||
| 6465 | .lookup = simple_lookup, | ||
| 6466 | .mkdir = instance_mkdir, | ||
| 6467 | .rmdir = instance_rmdir, | ||
| 6468 | }; | ||
| 6469 | |||
| 6470 | static __init void create_trace_instances(struct dentry *d_tracer) | 6406 | static __init void create_trace_instances(struct dentry *d_tracer) |
| 6471 | { | 6407 | { |
| 6472 | trace_instance_dir = tracefs_create_dir("instances", d_tracer); | 6408 | trace_instance_dir = tracefs_create_instance_dir("instances", d_tracer, |
| 6409 | instance_mkdir, | ||
| 6410 | instance_rmdir); | ||
| 6473 | if (WARN_ON(!trace_instance_dir)) | 6411 | if (WARN_ON(!trace_instance_dir)) |
| 6474 | return; | 6412 | return; |
| 6475 | |||
| 6476 | /* Hijack the dir inode operations, to allow mkdir */ | ||
| 6477 | trace_instance_dir->d_inode->i_op = &instance_dir_inode_operations; | ||
| 6478 | } | 6413 | } |
| 6479 | 6414 | ||
| 6480 | static void | 6415 | static void |
