linux/fs/debugfs/inode.c
<<
>>
Prefs
   1/*
   2 *  file.c - part of debugfs, a tiny little debug file system
   3 *
   4 *  Copyright (C) 2004 Greg Kroah-Hartman <greg@kroah.com>
   5 *  Copyright (C) 2004 IBM Inc.
   6 *
   7 *      This program is free software; you can redistribute it and/or
   8 *      modify it under the terms of the GNU General Public License version
   9 *      2 as published by the Free Software Foundation.
  10 *
  11 *  debugfs is for people to use instead of /proc or /sys.
  12 *  See Documentation/DocBook/kernel-api for more details.
  13 *
  14 */
  15
  16/* uncomment to get debug messages from the debug filesystem, ah the irony. */
  17/* #define DEBUG */
  18
  19#include <linux/module.h>
  20#include <linux/fs.h>
  21#include <linux/mount.h>
  22#include <linux/pagemap.h>
  23#include <linux/init.h>
  24#include <linux/kobject.h>
  25#include <linux/namei.h>
  26#include <linux/debugfs.h>
  27#include <linux/fsnotify.h>
  28#include <linux/string.h>
  29#include <linux/magic.h>
  30#include <linux/slab.h>
  31
  32static struct vfsmount *debugfs_mount;
  33static int debugfs_mount_count;
  34static bool debugfs_registered;
  35
  36static struct inode *debugfs_get_inode(struct super_block *sb, int mode, dev_t dev,
  37                                       void *data, const struct file_operations *fops)
  38
  39{
  40        struct inode *inode = new_inode(sb);
  41
  42        if (inode) {
  43                inode->i_mode = mode;
  44                inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
  45                switch (mode & S_IFMT) {
  46                default:
  47                        init_special_inode(inode, mode, dev);
  48                        break;
  49                case S_IFREG:
  50                        inode->i_fop = fops ? fops : &debugfs_file_operations;
  51                        inode->i_private = data;
  52                        break;
  53                case S_IFLNK:
  54                        inode->i_op = &debugfs_link_operations;
  55                        inode->i_fop = fops;
  56                        inode->i_private = data;
  57                        break;
  58                case S_IFDIR:
  59                        inode->i_op = &simple_dir_inode_operations;
  60                        inode->i_fop = fops ? fops : &simple_dir_operations;
  61                        inode->i_private = data;
  62
  63                        /* directory inodes start off with i_nlink == 2
  64                         * (for "." entry) */
  65                        inc_nlink(inode);
  66                        break;
  67                }
  68        }
  69        return inode; 
  70}
  71
  72/* SMP-safe */
  73static int debugfs_mknod(struct inode *dir, struct dentry *dentry,
  74                         int mode, dev_t dev, void *data,
  75                         const struct file_operations *fops)
  76{
  77        struct inode *inode;
  78        int error = -EPERM;
  79
  80        if (dentry->d_inode)
  81                return -EEXIST;
  82
  83        inode = debugfs_get_inode(dir->i_sb, mode, dev, data, fops);
  84        if (inode) {
  85                d_instantiate(dentry, inode);
  86                dget(dentry);
  87                error = 0;
  88        }
  89        return error;
  90}
  91
  92static int debugfs_mkdir(struct inode *dir, struct dentry *dentry, int mode,
  93                         void *data, const struct file_operations *fops)
  94{
  95        int res;
  96
  97        mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR;
  98        res = debugfs_mknod(dir, dentry, mode, 0, data, fops);
  99        if (!res) {
 100                inc_nlink(dir);
 101                fsnotify_mkdir(dir, dentry);
 102        }
 103        return res;
 104}
 105
 106static int debugfs_link(struct inode *dir, struct dentry *dentry, int mode,
 107                        void *data, const struct file_operations *fops)
 108{
 109        mode = (mode & S_IALLUGO) | S_IFLNK;
 110        return debugfs_mknod(dir, dentry, mode, 0, data, fops);
 111}
 112
 113static int debugfs_create(struct inode *dir, struct dentry *dentry, int mode,
 114                          void *data, const struct file_operations *fops)
 115{
 116        int res;
 117
 118        mode = (mode & S_IALLUGO) | S_IFREG;
 119        res = debugfs_mknod(dir, dentry, mode, 0, data, fops);
 120        if (!res)
 121                fsnotify_create(dir, dentry);
 122        return res;
 123}
 124
 125static inline int debugfs_positive(struct dentry *dentry)
 126{
 127        return dentry->d_inode && !d_unhashed(dentry);
 128}
 129
 130static int debug_fill_super(struct super_block *sb, void *data, int silent)
 131{
 132        static struct tree_descr debug_files[] = {{""}};
 133
 134        return simple_fill_super(sb, DEBUGFS_MAGIC, debug_files);
 135}
 136
 137static int debug_get_sb(struct file_system_type *fs_type,
 138                        int flags, const char *dev_name,
 139                        void *data, struct vfsmount *mnt)
 140{
 141        return get_sb_single(fs_type, flags, data, debug_fill_super, mnt);
 142}
 143
 144static struct file_system_type debug_fs_type = {
 145        .owner =        THIS_MODULE,
 146        .name =         "debugfs",
 147        .get_sb =       debug_get_sb,
 148        .kill_sb =      kill_litter_super,
 149};
 150
 151static int debugfs_create_by_name(const char *name, mode_t mode,
 152                                  struct dentry *parent,
 153                                  struct dentry **dentry,
 154                                  void *data,
 155                                  const struct file_operations *fops)
 156{
 157        int error = 0;
 158
 159        /* If the parent is not specified, we create it in the root.
 160         * We need the root dentry to do this, which is in the super 
 161         * block. A pointer to that is in the struct vfsmount that we
 162         * have around.
 163         */
 164        if (!parent)
 165                parent = debugfs_mount->mnt_sb->s_root;
 166
 167        *dentry = NULL;
 168        mutex_lock(&parent->d_inode->i_mutex);
 169        *dentry = lookup_one_len(name, parent, strlen(name));
 170        if (!IS_ERR(*dentry)) {
 171                switch (mode & S_IFMT) {
 172                case S_IFDIR:
 173                        error = debugfs_mkdir(parent->d_inode, *dentry, mode,
 174                                              data, fops);
 175                        break;
 176                case S_IFLNK:
 177                        error = debugfs_link(parent->d_inode, *dentry, mode,
 178                                             data, fops);
 179                        break;
 180                default:
 181                        error = debugfs_create(parent->d_inode, *dentry, mode,
 182                                               data, fops);
 183                        break;
 184                }
 185                dput(*dentry);
 186        } else
 187                error = PTR_ERR(*dentry);
 188        mutex_unlock(&parent->d_inode->i_mutex);
 189
 190        return error;
 191}
 192
 193/**
 194 * debugfs_create_file - create a file in the debugfs filesystem
 195 * @name: a pointer to a string containing the name of the file to create.
 196 * @mode: the permission that the file should have.
 197 * @parent: a pointer to the parent dentry for this file.  This should be a
 198 *          directory dentry if set.  If this paramater is NULL, then the
 199 *          file will be created in the root of the debugfs filesystem.
 200 * @data: a pointer to something that the caller will want to get to later
 201 *        on.  The inode.i_private pointer will point to this value on
 202 *        the open() call.
 203 * @fops: a pointer to a struct file_operations that should be used for
 204 *        this file.
 205 *
 206 * This is the basic "create a file" function for debugfs.  It allows for a
 207 * wide range of flexibility in creating a file, or a directory (if you want
 208 * to create a directory, the debugfs_create_dir() function is
 209 * recommended to be used instead.)
 210 *
 211 * This function will return a pointer to a dentry if it succeeds.  This
 212 * pointer must be passed to the debugfs_remove() function when the file is
 213 * to be removed (no automatic cleanup happens if your module is unloaded,
 214 * you are responsible here.)  If an error occurs, %NULL will be returned.
 215 *
 216 * If debugfs is not enabled in the kernel, the value -%ENODEV will be
 217 * returned.
 218 */
 219struct dentry *debugfs_create_file(const char *name, mode_t mode,
 220                                   struct dentry *parent, void *data,
 221                                   const struct file_operations *fops)
 222{
 223        struct dentry *dentry = NULL;
 224        int error;
 225
 226        pr_debug("debugfs: creating file '%s'\n",name);
 227
 228        error = simple_pin_fs(&debug_fs_type, &debugfs_mount,
 229                              &debugfs_mount_count);
 230        if (error)
 231                goto exit;
 232
 233        error = debugfs_create_by_name(name, mode, parent, &dentry,
 234                                       data, fops);
 235        if (error) {
 236                dentry = NULL;
 237                simple_release_fs(&debugfs_mount, &debugfs_mount_count);
 238                goto exit;
 239        }
 240exit:
 241        return dentry;
 242}
 243EXPORT_SYMBOL_GPL(debugfs_create_file);
 244
 245/**
 246 * debugfs_create_dir - create a directory in the debugfs filesystem
 247 * @name: a pointer to a string containing the name of the directory to
 248 *        create.
 249 * @parent: a pointer to the parent dentry for this file.  This should be a
 250 *          directory dentry if set.  If this paramater is NULL, then the
 251 *          directory will be created in the root of the debugfs filesystem.
 252 *
 253 * This function creates a directory in debugfs with the given name.
 254 *
 255 * This function will return a pointer to a dentry if it succeeds.  This
 256 * pointer must be passed to the debugfs_remove() function when the file is
 257 * to be removed (no automatic cleanup happens if your module is unloaded,
 258 * you are responsible here.)  If an error occurs, %NULL will be returned.
 259 *
 260 * If debugfs is not enabled in the kernel, the value -%ENODEV will be
 261 * returned.
 262 */
 263struct dentry *debugfs_create_dir(const char *name, struct dentry *parent)
 264{
 265        return debugfs_create_file(name, 
 266                                   S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO,
 267                                   parent, NULL, NULL);
 268}
 269EXPORT_SYMBOL_GPL(debugfs_create_dir);
 270
 271/**
 272 * debugfs_create_symlink- create a symbolic link in the debugfs filesystem
 273 * @name: a pointer to a string containing the name of the symbolic link to
 274 *        create.
 275 * @parent: a pointer to the parent dentry for this symbolic link.  This
 276 *          should be a directory dentry if set.  If this paramater is NULL,
 277 *          then the symbolic link will be created in the root of the debugfs
 278 *          filesystem.
 279 * @target: a pointer to a string containing the path to the target of the
 280 *          symbolic link.
 281 *
 282 * This function creates a symbolic link with the given name in debugfs that
 283 * links to the given target path.
 284 *
 285 * This function will return a pointer to a dentry if it succeeds.  This
 286 * pointer must be passed to the debugfs_remove() function when the symbolic
 287 * link is to be removed (no automatic cleanup happens if your module is
 288 * unloaded, you are responsible here.)  If an error occurs, %NULL will be
 289 * returned.
 290 *
 291 * If debugfs is not enabled in the kernel, the value -%ENODEV will be
 292 * returned.
 293 */
 294struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent,
 295                                      const char *target)
 296{
 297        struct dentry *result;
 298        char *link;
 299
 300        link = kstrdup(target, GFP_KERNEL);
 301        if (!link)
 302                return NULL;
 303
 304        result = debugfs_create_file(name, S_IFLNK | S_IRWXUGO, parent, link,
 305                                     NULL);
 306        if (!result)
 307                kfree(link);
 308        return result;
 309}
 310EXPORT_SYMBOL_GPL(debugfs_create_symlink);
 311
 312static void __debugfs_remove(struct dentry *dentry, struct dentry *parent)
 313{
 314        int ret = 0;
 315
 316        if (debugfs_positive(dentry)) {
 317                if (dentry->d_inode) {
 318                        dget(dentry);
 319                        switch (dentry->d_inode->i_mode & S_IFMT) {
 320                        case S_IFDIR:
 321                                ret = simple_rmdir(parent->d_inode, dentry);
 322                                break;
 323                        case S_IFLNK:
 324                                kfree(dentry->d_inode->i_private);
 325                                /* fall through */
 326                        default:
 327                                simple_unlink(parent->d_inode, dentry);
 328                                break;
 329                        }
 330                        if (!ret)
 331                                d_delete(dentry);
 332                        dput(dentry);
 333                }
 334        }
 335}
 336
 337/**
 338 * debugfs_remove - removes a file or directory from the debugfs filesystem
 339 * @dentry: a pointer to a the dentry of the file or directory to be
 340 *          removed.
 341 *
 342 * This function removes a file or directory in debugfs that was previously
 343 * created with a call to another debugfs function (like
 344 * debugfs_create_file() or variants thereof.)
 345 *
 346 * This function is required to be called in order for the file to be
 347 * removed, no automatic cleanup of files will happen when a module is
 348 * removed, you are responsible here.
 349 */
 350void debugfs_remove(struct dentry *dentry)
 351{
 352        struct dentry *parent;
 353        
 354        if (!dentry)
 355                return;
 356
 357        parent = dentry->d_parent;
 358        if (!parent || !parent->d_inode)
 359                return;
 360
 361        mutex_lock(&parent->d_inode->i_mutex);
 362        __debugfs_remove(dentry, parent);
 363        mutex_unlock(&parent->d_inode->i_mutex);
 364        simple_release_fs(&debugfs_mount, &debugfs_mount_count);
 365}
 366EXPORT_SYMBOL_GPL(debugfs_remove);
 367
 368/**
 369 * debugfs_remove_recursive - recursively removes a directory
 370 * @dentry: a pointer to a the dentry of the directory to be removed.
 371 *
 372 * This function recursively removes a directory tree in debugfs that
 373 * was previously created with a call to another debugfs function
 374 * (like debugfs_create_file() or variants thereof.)
 375 *
 376 * This function is required to be called in order for the file to be
 377 * removed, no automatic cleanup of files will happen when a module is
 378 * removed, you are responsible here.
 379 */
 380void debugfs_remove_recursive(struct dentry *dentry)
 381{
 382        struct dentry *child;
 383        struct dentry *parent;
 384
 385        if (!dentry)
 386                return;
 387
 388        parent = dentry->d_parent;
 389        if (!parent || !parent->d_inode)
 390                return;
 391
 392        parent = dentry;
 393        mutex_lock(&parent->d_inode->i_mutex);
 394
 395        while (1) {
 396                /*
 397                 * When all dentries under "parent" has been removed,
 398                 * walk up the tree until we reach our starting point.
 399                 */
 400                if (list_empty(&parent->d_subdirs)) {
 401                        mutex_unlock(&parent->d_inode->i_mutex);
 402                        if (parent == dentry)
 403                                break;
 404                        parent = parent->d_parent;
 405                        mutex_lock(&parent->d_inode->i_mutex);
 406                }
 407                child = list_entry(parent->d_subdirs.next, struct dentry,
 408                                d_u.d_child);
 409 next_sibling:
 410
 411                /*
 412                 * If "child" isn't empty, walk down the tree and
 413                 * remove all its descendants first.
 414                 */
 415                if (!list_empty(&child->d_subdirs)) {
 416                        mutex_unlock(&parent->d_inode->i_mutex);
 417                        parent = child;
 418                        mutex_lock(&parent->d_inode->i_mutex);
 419                        continue;
 420                }
 421                __debugfs_remove(child, parent);
 422                if (parent->d_subdirs.next == &child->d_u.d_child) {
 423                        /*
 424                         * Try the next sibling.
 425                         */
 426                        if (child->d_u.d_child.next != &parent->d_subdirs) {
 427                                child = list_entry(child->d_u.d_child.next,
 428                                                   struct dentry,
 429                                                   d_u.d_child);
 430                                goto next_sibling;
 431                        }
 432
 433                        /*
 434                         * Avoid infinite loop if we fail to remove
 435                         * one dentry.
 436                         */
 437                        mutex_unlock(&parent->d_inode->i_mutex);
 438                        break;
 439                }
 440                simple_release_fs(&debugfs_mount, &debugfs_mount_count);
 441        }
 442
 443        parent = dentry->d_parent;
 444        mutex_lock(&parent->d_inode->i_mutex);
 445        __debugfs_remove(dentry, parent);
 446        mutex_unlock(&parent->d_inode->i_mutex);
 447        simple_release_fs(&debugfs_mount, &debugfs_mount_count);
 448}
 449EXPORT_SYMBOL_GPL(debugfs_remove_recursive);
 450
 451/**
 452 * debugfs_rename - rename a file/directory in the debugfs filesystem
 453 * @old_dir: a pointer to the parent dentry for the renamed object. This
 454 *          should be a directory dentry.
 455 * @old_dentry: dentry of an object to be renamed.
 456 * @new_dir: a pointer to the parent dentry where the object should be
 457 *          moved. This should be a directory dentry.
 458 * @new_name: a pointer to a string containing the target name.
 459 *
 460 * This function renames a file/directory in debugfs.  The target must not
 461 * exist for rename to succeed.
 462 *
 463 * This function will return a pointer to old_dentry (which is updated to
 464 * reflect renaming) if it succeeds. If an error occurs, %NULL will be
 465 * returned.
 466 *
 467 * If debugfs is not enabled in the kernel, the value -%ENODEV will be
 468 * returned.
 469 */
 470struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry,
 471                struct dentry *new_dir, const char *new_name)
 472{
 473        int error;
 474        struct dentry *dentry = NULL, *trap;
 475        const char *old_name;
 476
 477        trap = lock_rename(new_dir, old_dir);
 478        /* Source or destination directories don't exist? */
 479        if (!old_dir->d_inode || !new_dir->d_inode)
 480                goto exit;
 481        /* Source does not exist, cyclic rename, or mountpoint? */
 482        if (!old_dentry->d_inode || old_dentry == trap ||
 483            d_mountpoint(old_dentry))
 484                goto exit;
 485        dentry = lookup_one_len(new_name, new_dir, strlen(new_name));
 486        /* Lookup failed, cyclic rename or target exists? */
 487        if (IS_ERR(dentry) || dentry == trap || dentry->d_inode)
 488                goto exit;
 489
 490        old_name = fsnotify_oldname_init(old_dentry->d_name.name);
 491
 492        error = simple_rename(old_dir->d_inode, old_dentry, new_dir->d_inode,
 493                dentry);
 494        if (error) {
 495                fsnotify_oldname_free(old_name);
 496                goto exit;
 497        }
 498        d_move(old_dentry, dentry);
 499        fsnotify_move(old_dir->d_inode, new_dir->d_inode, old_name,
 500                S_ISDIR(old_dentry->d_inode->i_mode),
 501                NULL, old_dentry);
 502        fsnotify_oldname_free(old_name);
 503        unlock_rename(new_dir, old_dir);
 504        dput(dentry);
 505        return old_dentry;
 506exit:
 507        if (dentry && !IS_ERR(dentry))
 508                dput(dentry);
 509        unlock_rename(new_dir, old_dir);
 510        return NULL;
 511}
 512EXPORT_SYMBOL_GPL(debugfs_rename);
 513
 514/**
 515 * debugfs_initialized - Tells whether debugfs has been registered
 516 */
 517bool debugfs_initialized(void)
 518{
 519        return debugfs_registered;
 520}
 521EXPORT_SYMBOL_GPL(debugfs_initialized);
 522
 523
 524static struct kobject *debug_kobj;
 525
 526static int __init debugfs_init(void)
 527{
 528        int retval;
 529
 530        debug_kobj = kobject_create_and_add("debug", kernel_kobj);
 531        if (!debug_kobj)
 532                return -EINVAL;
 533
 534        retval = register_filesystem(&debug_fs_type);
 535        if (retval)
 536                kobject_put(debug_kobj);
 537        else
 538                debugfs_registered = true;
 539
 540        return retval;
 541}
 542
 543static void __exit debugfs_exit(void)
 544{
 545        debugfs_registered = false;
 546
 547        simple_release_fs(&debugfs_mount, &debugfs_mount_count);
 548        unregister_filesystem(&debug_fs_type);
 549        kobject_put(debug_kobj);
 550}
 551
 552core_initcall(debugfs_init);
 553module_exit(debugfs_exit);
 554MODULE_LICENSE("GPL");
 555
 556
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.