linux/fs/debugfs/file.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#include <linux/module.h>
  17#include <linux/fs.h>
  18#include <linux/pagemap.h>
  19#include <linux/namei.h>
  20#include <linux/debugfs.h>
  21
  22static ssize_t default_read_file(struct file *file, char __user *buf,
  23                                 size_t count, loff_t *ppos)
  24{
  25        return 0;
  26}
  27
  28static ssize_t default_write_file(struct file *file, const char __user *buf,
  29                                   size_t count, loff_t *ppos)
  30{
  31        return count;
  32}
  33
  34static int default_open(struct inode *inode, struct file *file)
  35{
  36        if (inode->i_private)
  37                file->private_data = inode->i_private;
  38
  39        return 0;
  40}
  41
  42const struct file_operations debugfs_file_operations = {
  43        .read =         default_read_file,
  44        .write =        default_write_file,
  45        .open =         default_open,
  46};
  47
  48static void *debugfs_follow_link(struct dentry *dentry, struct nameidata *nd)
  49{
  50        nd_set_link(nd, dentry->d_inode->i_private);
  51        return NULL;
  52}
  53
  54const struct inode_operations debugfs_link_operations = {
  55        .readlink       = generic_readlink,
  56        .follow_link    = debugfs_follow_link,
  57};
  58
  59static void debugfs_u8_set(void *data, u64 val)
  60{
  61        *(u8 *)data = val;
  62}
  63static u64 debugfs_u8_get(void *data)
  64{
  65        return *(u8 *)data;
  66}
  67DEFINE_SIMPLE_ATTRIBUTE(fops_u8, debugfs_u8_get, debugfs_u8_set, "%llu\n");
  68
  69/**
  70 * debugfs_create_u8 - create a debugfs file that is used to read and write an unsigned 8-bit value
  71 * @name: a pointer to a string containing the name of the file to create.
  72 * @mode: the permission that the file should have
  73 * @parent: a pointer to the parent dentry for this file.  This should be a
  74 *          directory dentry if set.  If this parameter is %NULL, then the
  75 *          file will be created in the root of the debugfs filesystem.
  76 * @value: a pointer to the variable that the file should read to and write
  77 *         from.
  78 *
  79 * This function creates a file in debugfs with the given name that
  80 * contains the value of the variable @value.  If the @mode variable is so
  81 * set, it can be read from, and written to.
  82 *
  83 * This function will return a pointer to a dentry if it succeeds.  This
  84 * pointer must be passed to the debugfs_remove() function when the file is
  85 * to be removed (no automatic cleanup happens if your module is unloaded,
  86 * you are responsible here.)  If an error occurs, %NULL will be returned.
  87 *
  88 * If debugfs is not enabled in the kernel, the value -%ENODEV will be
  89 * returned.  It is not wise to check for this value, but rather, check for
  90 * %NULL or !%NULL instead as to eliminate the need for #ifdef in the calling
  91 * code.
  92 */
  93struct dentry *debugfs_create_u8(const char *name, mode_t mode,
  94                                 struct dentry *parent, u8 *value)
  95{
  96        return debugfs_create_file(name, mode, parent, value, &fops_u8);
  97}
  98EXPORT_SYMBOL_GPL(debugfs_create_u8);
  99
 100static void debugfs_u16_set(void *data, u64 val)
 101{
 102        *(u16 *)data = val;
 103}
 104static u64 debugfs_u16_get(void *data)
 105{
 106        return *(u16 *)data;
 107}
 108DEFINE_SIMPLE_ATTRIBUTE(fops_u16, debugfs_u16_get, debugfs_u16_set, "%llu\n");
 109
 110/**
 111 * debugfs_create_u16 - create a debugfs file that is used to read and write an unsigned 16-bit value
 112 * @name: a pointer to a string containing the name of the file to create.
 113 * @mode: the permission that the file should have
 114 * @parent: a pointer to the parent dentry for this file.  This should be a
 115 *          directory dentry if set.  If this parameter is %NULL, then the
 116 *          file will be created in the root of the debugfs filesystem.
 117 * @value: a pointer to the variable that the file should read to and write
 118 *         from.
 119 *
 120 * This function creates a file in debugfs with the given name that
 121 * contains the value of the variable @value.  If the @mode variable is so
 122 * set, it can be read from, and written to.
 123 *
 124 * This function will return a pointer to a dentry if it succeeds.  This
 125 * pointer must be passed to the debugfs_remove() function when the file is
 126 * to be removed (no automatic cleanup happens if your module is unloaded,
 127 * you are responsible here.)  If an error occurs, %NULL will be returned.
 128 *
 129 * If debugfs is not enabled in the kernel, the value -%ENODEV will be
 130 * returned.  It is not wise to check for this value, but rather, check for
 131 * %NULL or !%NULL instead as to eliminate the need for #ifdef in the calling
 132 * code.
 133 */
 134struct dentry *debugfs_create_u16(const char *name, mode_t mode,
 135                                  struct dentry *parent, u16 *value)
 136{
 137        return debugfs_create_file(name, mode, parent, value, &fops_u16);
 138}
 139EXPORT_SYMBOL_GPL(debugfs_create_u16);
 140
 141static void debugfs_u32_set(void *data, u64 val)
 142{
 143        *(u32 *)data = val;
 144}
 145static u64 debugfs_u32_get(void *data)
 146{
 147        return *(u32 *)data;
 148}
 149DEFINE_SIMPLE_ATTRIBUTE(fops_u32, debugfs_u32_get, debugfs_u32_set, "%llu\n");
 150
 151/**
 152 * debugfs_create_u32 - create a debugfs file that is used to read and write an unsigned 32-bit value
 153 * @name: a pointer to a string containing the name of the file to create.
 154 * @mode: the permission that the file should have
 155 * @parent: a pointer to the parent dentry for this file.  This should be a
 156 *          directory dentry if set.  If this parameter is %NULL, then the
 157 *          file will be created in the root of the debugfs filesystem.
 158 * @value: a pointer to the variable that the file should read to and write
 159 *         from.
 160 *
 161 * This function creates a file in debugfs with the given name that
 162 * contains the value of the variable @value.  If the @mode variable is so
 163 * set, it can be read from, and written to.
 164 *
 165 * This function will return a pointer to a dentry if it succeeds.  This
 166 * pointer must be passed to the debugfs_remove() function when the file is
 167 * to be removed (no automatic cleanup happens if your module is unloaded,
 168 * you are responsible here.)  If an error occurs, %NULL will be returned.
 169 *
 170 * If debugfs is not enabled in the kernel, the value -%ENODEV will be
 171 * returned.  It is not wise to check for this value, but rather, check for
 172 * %NULL or !%NULL instead as to eliminate the need for #ifdef in the calling
 173 * code.
 174 */
 175struct dentry *debugfs_create_u32(const char *name, mode_t mode,
 176                                 struct dentry *parent, u32 *value)
 177{
 178        return debugfs_create_file(name, mode, parent, value, &fops_u32);
 179}
 180EXPORT_SYMBOL_GPL(debugfs_create_u32);
 181
 182static void debugfs_u64_set(void *data, u64 val)
 183{
 184        *(u64 *)data = val;
 185}
 186
 187static u64 debugfs_u64_get(void *data)
 188{
 189        return *(u64 *)data;
 190}
 191DEFINE_SIMPLE_ATTRIBUTE(fops_u64, debugfs_u64_get, debugfs_u64_set, "%llu\n");
 192
 193/**
 194 * debugfs_create_u64 - create a debugfs file that is used to read and write an unsigned 64-bit value
 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 parameter is %NULL, then the
 199 *          file will be created in the root of the debugfs filesystem.
 200 * @value: a pointer to the variable that the file should read to and write
 201 *         from.
 202 *
 203 * This function creates a file in debugfs with the given name that
 204 * contains the value of the variable @value.  If the @mode variable is so
 205 * set, it can be read from, and written to.
 206 *
 207 * This function will return a pointer to a dentry if it succeeds.  This
 208 * pointer must be passed to the debugfs_remove() function when the file is
 209 * to be removed (no automatic cleanup happens if your module is unloaded,
 210 * you are responsible here.)  If an error occurs, %NULL will be returned.
 211 *
 212 * If debugfs is not enabled in the kernel, the value -%ENODEV will be
 213 * returned.  It is not wise to check for this value, but rather, check for
 214 * %NULL or !%NULL instead as to eliminate the need for #ifdef in the calling
 215 * code.
 216 */
 217struct dentry *debugfs_create_u64(const char *name, mode_t mode,
 218                                 struct dentry *parent, u64 *value)
 219{
 220        return debugfs_create_file(name, mode, parent, value, &fops_u64);
 221}
 222EXPORT_SYMBOL_GPL(debugfs_create_u64);
 223
 224DEFINE_SIMPLE_ATTRIBUTE(fops_x8, debugfs_u8_get, debugfs_u8_set, "0x%02llx\n");
 225
 226DEFINE_SIMPLE_ATTRIBUTE(fops_x16, debugfs_u16_get, debugfs_u16_set, "0x%04llx\n");
 227
 228DEFINE_SIMPLE_ATTRIBUTE(fops_x32, debugfs_u32_get, debugfs_u32_set, "0x%08llx\n");
 229
 230/*
 231 * debugfs_create_x{8,16,32} - create a debugfs file that is used to read and write an unsigned {8,16,32}-bit value
 232 *
 233 * These functions are exactly the same as the above functions (but use a hex
 234 * output for the decimal challenged). For details look at the above unsigned
 235 * decimal functions.
 236 */
 237
 238/**
 239 * debugfs_create_x8 - create a debugfs file that is used to read and write an unsigned 8-bit value
 240 * @name: a pointer to a string containing the name of the file to create.
 241 * @mode: the permission that the file should have
 242 * @parent: a pointer to the parent dentry for this file.  This should be a
 243 *          directory dentry if set.  If this parameter is %NULL, then the
 244 *          file will be created in the root of the debugfs filesystem.
 245 * @value: a pointer to the variable that the file should read to and write
 246 *         from.
 247 */
 248struct dentry *debugfs_create_x8(const char *name, mode_t mode,
 249                                 struct dentry *parent, u8 *value)
 250{
 251        return debugfs_create_file(name, mode, parent, value, &fops_x8);
 252}
 253EXPORT_SYMBOL_GPL(debugfs_create_x8);
 254
 255/**
 256 * debugfs_create_x16 - create a debugfs file that is used to read and write an unsigned 16-bit value
 257 * @name: a pointer to a string containing the name of the file to create.
 258 * @mode: the permission that the file should have
 259 * @parent: a pointer to the parent dentry for this file.  This should be a
 260 *          directory dentry if set.  If this parameter is %NULL, then the
 261 *          file will be created in the root of the debugfs filesystem.
 262 * @value: a pointer to the variable that the file should read to and write
 263 *         from.
 264 */
 265struct dentry *debugfs_create_x16(const char *name, mode_t mode,
 266                                 struct dentry *parent, u16 *value)
 267{
 268        return debugfs_create_file(name, mode, parent, value, &fops_x16);
 269}
 270EXPORT_SYMBOL_GPL(debugfs_create_x16);
 271
 272/**
 273 * debugfs_create_x32 - create a debugfs file that is used to read and write an unsigned 32-bit value
 274 * @name: a pointer to a string containing the name of the file to create.
 275 * @mode: the permission that the file should have
 276 * @parent: a pointer to the parent dentry for this file.  This should be a
 277 *          directory dentry if set.  If this parameter is %NULL, then the
 278 *          file will be created in the root of the debugfs filesystem.
 279 * @value: a pointer to the variable that the file should read to and write
 280 *         from.
 281 */
 282struct dentry *debugfs_create_x32(const char *name, mode_t mode,
 283                                 struct dentry *parent, u32 *value)
 284{
 285        return debugfs_create_file(name, mode, parent, value, &fops_x32);
 286}
 287EXPORT_SYMBOL_GPL(debugfs_create_x32);
 288
 289static ssize_t read_file_bool(struct file *file, char __user *user_buf,
 290                              size_t count, loff_t *ppos)
 291{
 292        char buf[3];
 293        u32 *val = file->private_data;
 294        
 295        if (*val)
 296                buf[0] = 'Y';
 297        else
 298                buf[0] = 'N';
 299        buf[1] = '\n';
 300        buf[2] = 0x00;
 301        return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
 302}
 303
 304static ssize_t write_file_bool(struct file *file, const char __user *user_buf,
 305                               size_t count, loff_t *ppos)
 306{
 307        char buf[32];
 308        int buf_size;
 309        u32 *val = file->private_data;
 310
 311        buf_size = min(count, (sizeof(buf)-1));
 312        if (copy_from_user(buf, user_buf, buf_size))
 313                return -EFAULT;
 314
 315        switch (buf[0]) {
 316        case 'y':
 317        case 'Y':
 318        case '1':
 319                *val = 1;
 320                break;
 321        case 'n':
 322        case 'N':
 323        case '0':
 324                *val = 0;
 325                break;
 326        }
 327        
 328        return count;
 329}
 330
 331static const struct file_operations fops_bool = {
 332        .read =         read_file_bool,
 333        .write =        write_file_bool,
 334        .open =         default_open,
 335};
 336
 337/**
 338 * debugfs_create_bool - create a debugfs file that is used to read and write a boolean value
 339 * @name: a pointer to a string containing the name of the file to create.
 340 * @mode: the permission that the file should have
 341 * @parent: a pointer to the parent dentry for this file.  This should be a
 342 *          directory dentry if set.  If this parameter is %NULL, then the
 343 *          file will be created in the root of the debugfs filesystem.
 344 * @value: a pointer to the variable that the file should read to and write
 345 *         from.
 346 *
 347 * This function creates a file in debugfs with the given name that
 348 * contains the value of the variable @value.  If the @mode variable is so
 349 * set, it can be read from, and written to.
 350 *
 351 * This function will return a pointer to a dentry if it succeeds.  This
 352 * pointer must be passed to the debugfs_remove() function when the file is
 353 * to be removed (no automatic cleanup happens if your module is unloaded,
 354 * you are responsible here.)  If an error occurs, %NULL will be returned.
 355 *
 356 * If debugfs is not enabled in the kernel, the value -%ENODEV will be
 357 * returned.  It is not wise to check for this value, but rather, check for
 358 * %NULL or !%NULL instead as to eliminate the need for #ifdef in the calling
 359 * code.
 360 */
 361struct dentry *debugfs_create_bool(const char *name, mode_t mode,
 362                                   struct dentry *parent, u32 *value)
 363{
 364        return debugfs_create_file(name, mode, parent, value, &fops_bool);
 365}
 366EXPORT_SYMBOL_GPL(debugfs_create_bool);
 367
 368static ssize_t read_file_blob(struct file *file, char __user *user_buf,
 369                              size_t count, loff_t *ppos)
 370{
 371        struct debugfs_blob_wrapper *blob = file->private_data;
 372        return simple_read_from_buffer(user_buf, count, ppos, blob->data,
 373                        blob->size);
 374}
 375
 376static const struct file_operations fops_blob = {
 377        .read =         read_file_blob,
 378        .open =         default_open,
 379};
 380
 381/**
 382 * debugfs_create_blob - create a debugfs file that is used to read and write a binary blob
 383 * @name: a pointer to a string containing the name of the file to create.
 384 * @mode: the permission that the file should have
 385 * @parent: a pointer to the parent dentry for this file.  This should be a
 386 *          directory dentry if set.  If this parameter is %NULL, then the
 387 *          file will be created in the root of the debugfs filesystem.
 388 * @blob: a pointer to a struct debugfs_blob_wrapper which contains a pointer
 389 *        to the blob data and the size of the data.
 390 *
 391 * This function creates a file in debugfs with the given name that exports
 392 * @blob->data as a binary blob. If the @mode variable is so set it can be
 393 * read from. Writing is not supported.
 394 *
 395 * This function will return a pointer to a dentry if it succeeds.  This
 396 * pointer must be passed to the debugfs_remove() function when the file is
 397 * to be removed (no automatic cleanup happens if your module is unloaded,
 398 * you are responsible here.)  If an error occurs, %NULL will be returned.
 399 *
 400 * If debugfs is not enabled in the kernel, the value -%ENODEV will be
 401 * returned.  It is not wise to check for this value, but rather, check for
 402 * %NULL or !%NULL instead as to eliminate the need for #ifdef in the calling
 403 * code.
 404 */
 405struct dentry *debugfs_create_blob(const char *name, mode_t mode,
 406                                   struct dentry *parent,
 407                                   struct debugfs_blob_wrapper *blob)
 408{
 409        return debugfs_create_file(name, mode, parent, blob, &fops_blob);
 410}
 411EXPORT_SYMBOL_GPL(debugfs_create_blob);
 412