lkml.org 
[lkml]   [2017]   [Sep]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[RFC PATCH 04/17] tracefs: Add ->unlink callback to tracefs_dir_ops
    Date
    In addition to mkdir and rmdir, also allow unlink operation within the
    'instances' directory if such callback is defined.

    Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
    Cc: Steven Rostedt <rostedt@goodmis.org>
    ---
    fs/tracefs/inode.c | 36 +++++++++++++++++++++++++++++++++++-
    include/linux/tracefs.h | 3 ++-
    kernel/trace/trace.c | 8 +++++++-
    3 files changed, 44 insertions(+), 3 deletions(-)

    diff --git a/fs/tracefs/inode.c b/fs/tracefs/inode.c
    index b14f03a655..fba5a0ce07 100644
    --- a/fs/tracefs/inode.c
    +++ b/fs/tracefs/inode.c
    @@ -53,6 +53,7 @@ static const struct file_operations tracefs_file_operations = {
    struct tracefs_dir_ops {
    int (*mkdir)(const char *name);
    int (*rmdir)(const char *name);
    + int (*unlink)(const char *name);
    };

    static char *get_dname(struct dentry *dentry)
    @@ -124,10 +125,41 @@ static int tracefs_syscall_rmdir(struct inode *inode, struct dentry *dentry)
    return ret;
    }

    +static int tracefs_syscall_unlink(struct inode *inode, struct dentry *dentry)
    +{
    + struct tracefs_dir_ops *tracefs_ops = dentry->d_fsdata;
    + char *name;
    + int ret;
    +
    + name = get_dname(dentry);
    + if (!name)
    + return -ENOMEM;
    +
    + /*
    + * The unlink call can call the generic functions that create
    + * the files within the tracefs system. It is up to the individual
    + * unlink routine to handle races.
    + * This time we need to unlock not only the parent (inode) but
    + * also the file that is being deleted.
    + */
    + inode_unlock(inode);
    + inode_unlock(dentry->d_inode);
    +
    + ret = tracefs_ops->unlink(name);
    +
    + inode_lock_nested(inode, I_MUTEX_PARENT);
    + inode_lock(dentry->d_inode);
    +
    + kfree(name);
    +
    + return ret;
    +}
    +
    static const struct inode_operations tracefs_dir_inode_operations = {
    .lookup = simple_lookup,
    .mkdir = tracefs_syscall_mkdir,
    .rmdir = tracefs_syscall_rmdir,
    + .unlink = tracefs_syscall_unlink,
    };

    static struct inode *tracefs_get_inode(struct super_block *sb)
    @@ -485,7 +517,8 @@ struct dentry *tracefs_create_dir(const char *name, struct dentry *parent)
    */
    struct dentry *tracefs_create_instance_dir(const char *name, struct dentry *parent,
    int (*mkdir)(const char *name),
    - int (*rmdir)(const char *name))
    + int (*rmdir)(const char *name),
    + int (*unlink)(const char *name))
    {
    struct tracefs_dir_ops *tracefs_ops = parent ? parent->d_fsdata : NULL;
    struct dentry *dentry;
    @@ -505,6 +538,7 @@ struct dentry *tracefs_create_instance_dir(const char *name, struct dentry *pare

    tracefs_ops->mkdir = mkdir;
    tracefs_ops->rmdir = rmdir;
    + tracefs_ops->unlink = unlink;
    dentry->d_fsdata = tracefs_ops;

    return dentry;
    diff --git a/include/linux/tracefs.h b/include/linux/tracefs.h
    index 5b727a17be..e5bd1f01b6 100644
    --- a/include/linux/tracefs.h
    +++ b/include/linux/tracefs.h
    @@ -36,7 +36,8 @@ void tracefs_remove_recursive(struct dentry *dentry);

    struct dentry *tracefs_create_instance_dir(const char *name, struct dentry *parent,
    int (*mkdir)(const char *name),
    - int (*rmdir)(const char *name));
    + int (*rmdir)(const char *name),
    + int (*unlink)(const char *name));

    bool tracefs_initialized(void);

    diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
    index 44004d8aa3..b9abd2029e 100644
    --- a/kernel/trace/trace.c
    +++ b/kernel/trace/trace.c
    @@ -7792,11 +7792,17 @@ static int instance_rmdir(const char *name)
    return ret;
    }

    +static int instance_unlink(const char *name)
    +{
    + return -EACCES;
    +}
    +
    static __init void create_trace_instances(struct dentry *d_tracer)
    {
    trace_instance_dir = tracefs_create_instance_dir("instances", d_tracer,
    instance_mkdir,
    - instance_rmdir);
    + instance_rmdir,
    + instance_unlink);
    if (WARN_ON(!trace_instance_dir))
    return;
    }
    --
    2.14.1
    \
     
     \ /
      Last update: 2017-09-05 15:35    [W:4.369 / U:0.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site