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