linux/fs/configfs/file.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/* -*- mode: c; c-basic-offset: 8; -*-
   3 * vim: noexpandtab sw=8 ts=8 sts=0:
   4 *
   5 * file.c - operations for regular (text) files.
   6 *
   7 * Based on sysfs:
   8 *      sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel
   9 *
  10 * configfs Copyright (C) 2005 Oracle.  All rights reserved.
  11 */
  12
  13#include <linux/fs.h>
  14#include <linux/module.h>
  15#include <linux/slab.h>
  16#include <linux/mutex.h>
  17#include <linux/vmalloc.h>
  18#include <linux/uaccess.h>
  19
  20#include <linux/configfs.h>
  21#include "configfs_internal.h"
  22
  23/*
  24 * A simple attribute can only be 4096 characters.  Why 4k?  Because the
  25 * original code limited it to PAGE_SIZE.  That's a bad idea, though,
  26 * because an attribute of 16k on ia64 won't work on x86.  So we limit to
  27 * 4k, our minimum common page size.
  28 */
  29#define SIMPLE_ATTR_SIZE 4096
  30
  31struct configfs_buffer {
  32        size_t                  count;
  33        loff_t                  pos;
  34        char                    * page;
  35        struct configfs_item_operations * ops;
  36        struct mutex            mutex;
  37        int                     needs_read_fill;
  38        bool                    read_in_progress;
  39        bool                    write_in_progress;
  40        char                    *bin_buffer;
  41        int                     bin_buffer_size;
  42        int                     cb_max_size;
  43        struct config_item      *item;
  44        struct module           *owner;
  45        union {
  46                struct configfs_attribute       *attr;
  47                struct configfs_bin_attribute   *bin_attr;
  48        };
  49};
  50
  51static inline struct configfs_fragment *to_frag(struct file *file)
  52{
  53        struct configfs_dirent *sd = file->f_path.dentry->d_fsdata;
  54
  55        return sd->s_frag;
  56}
  57
  58static int fill_read_buffer(struct file *file, struct configfs_buffer *buffer)
  59{
  60        struct configfs_fragment *frag = to_frag(file);
  61        ssize_t count = -ENOENT;
  62
  63        if (!buffer->page)
  64                buffer->page = (char *) get_zeroed_page(GFP_KERNEL);
  65        if (!buffer->page)
  66                return -ENOMEM;
  67
  68        down_read(&frag->frag_sem);
  69        if (!frag->frag_dead)
  70                count = buffer->attr->show(buffer->item, buffer->page);
  71        up_read(&frag->frag_sem);
  72
  73        if (count < 0)
  74                return count;
  75        if (WARN_ON_ONCE(count > (ssize_t)SIMPLE_ATTR_SIZE))
  76                return -EIO;
  77        buffer->needs_read_fill = 0;
  78        buffer->count = count;
  79        return 0;
  80}
  81
  82/**
  83 *      configfs_read_file - read an attribute.
  84 *      @file:  file pointer.
  85 *      @buf:   buffer to fill.
  86 *      @count: number of bytes to read.
  87 *      @ppos:  starting offset in file.
  88 *
  89 *      Userspace wants to read an attribute file. The attribute descriptor
  90 *      is in the file's ->d_fsdata. The target item is in the directory's
  91 *      ->d_fsdata.
  92 *
  93 *      We call fill_read_buffer() to allocate and fill the buffer from the
  94 *      item's show() method exactly once (if the read is happening from
  95 *      the beginning of the file). That should fill the entire buffer with
  96 *      all the data the item has to offer for that attribute.
  97 *      We then call flush_read_buffer() to copy the buffer to userspace
  98 *      in the increments specified.
  99 */
 100
 101static ssize_t
 102configfs_read_file(struct file *file, char __user *buf, size_t count, loff_t *ppos)
 103{
 104        struct configfs_buffer *buffer = file->private_data;
 105        ssize_t retval = 0;
 106
 107        mutex_lock(&buffer->mutex);
 108        if (buffer->needs_read_fill) {
 109                retval = fill_read_buffer(file, buffer);
 110                if (retval)
 111                        goto out;
 112        }
 113        pr_debug("%s: count = %zd, ppos = %lld, buf = %s\n",
 114                 __func__, count, *ppos, buffer->page);
 115        retval = simple_read_from_buffer(buf, count, ppos, buffer->page,
 116                                         buffer->count);
 117out:
 118        mutex_unlock(&buffer->mutex);
 119        return retval;
 120}
 121
 122/**
 123 *      configfs_read_bin_file - read a binary attribute.
 124 *      @file:  file pointer.
 125 *      @buf:   buffer to fill.
 126 *      @count: number of bytes to read.
 127 *      @ppos:  starting offset in file.
 128 *
 129 *      Userspace wants to read a binary attribute file. The attribute
 130 *      descriptor is in the file's ->d_fsdata. The target item is in the
 131 *      directory's ->d_fsdata.
 132 *
 133 *      We check whether we need to refill the buffer. If so we will
 134 *      call the attributes' attr->read() twice. The first time we
 135 *      will pass a NULL as a buffer pointer, which the attributes' method
 136 *      will use to return the size of the buffer required. If no error
 137 *      occurs we will allocate the buffer using vmalloc and call
 138 *      attr->read() again passing that buffer as an argument.
 139 *      Then we just copy to user-space using simple_read_from_buffer.
 140 */
 141
 142static ssize_t
 143configfs_read_bin_file(struct file *file, char __user *buf,
 144                       size_t count, loff_t *ppos)
 145{
 146        struct configfs_fragment *frag = to_frag(file);
 147        struct configfs_buffer *buffer = file->private_data;
 148        ssize_t retval = 0;
 149        ssize_t len = min_t(size_t, count, PAGE_SIZE);
 150
 151        mutex_lock(&buffer->mutex);
 152
 153        /* we don't support switching read/write modes */
 154        if (buffer->write_in_progress) {
 155                retval = -ETXTBSY;
 156                goto out;
 157        }
 158        buffer->read_in_progress = true;
 159
 160        if (buffer->needs_read_fill) {
 161                /* perform first read with buf == NULL to get extent */
 162                down_read(&frag->frag_sem);
 163                if (!frag->frag_dead)
 164                        len = buffer->bin_attr->read(buffer->item, NULL, 0);
 165                else
 166                        len = -ENOENT;
 167                up_read(&frag->frag_sem);
 168                if (len <= 0) {
 169                        retval = len;
 170                        goto out;
 171                }
 172
 173                /* do not exceed the maximum value */
 174                if (buffer->cb_max_size && len > buffer->cb_max_size) {
 175                        retval = -EFBIG;
 176                        goto out;
 177                }
 178
 179                buffer->bin_buffer = vmalloc(len);
 180                if (buffer->bin_buffer == NULL) {
 181                        retval = -ENOMEM;
 182                        goto out;
 183                }
 184                buffer->bin_buffer_size = len;
 185
 186                /* perform second read to fill buffer */
 187                down_read(&frag->frag_sem);
 188                if (!frag->frag_dead)
 189                        len = buffer->bin_attr->read(buffer->item,
 190                                                     buffer->bin_buffer, len);
 191                else
 192                        len = -ENOENT;
 193                up_read(&frag->frag_sem);
 194                if (len < 0) {
 195                        retval = len;
 196                        vfree(buffer->bin_buffer);
 197                        buffer->bin_buffer_size = 0;
 198                        buffer->bin_buffer = NULL;
 199                        goto out;
 200                }
 201
 202                buffer->needs_read_fill = 0;
 203        }
 204
 205        retval = simple_read_from_buffer(buf, count, ppos, buffer->bin_buffer,
 206                                        buffer->bin_buffer_size);
 207out:
 208        mutex_unlock(&buffer->mutex);
 209        return retval;
 210}
 211
 212
 213/**
 214 *      fill_write_buffer - copy buffer from userspace.
 215 *      @buffer:        data buffer for file.
 216 *      @buf:           data from user.
 217 *      @count:         number of bytes in @userbuf.
 218 *
 219 *      Allocate @buffer->page if it hasn't been already, then
 220 *      copy the user-supplied buffer into it.
 221 */
 222
 223static int
 224fill_write_buffer(struct configfs_buffer * buffer, const char __user * buf, size_t count)
 225{
 226        int error;
 227
 228        if (!buffer->page)
 229                buffer->page = (char *)__get_free_pages(GFP_KERNEL, 0);
 230        if (!buffer->page)
 231                return -ENOMEM;
 232
 233        if (count >= SIMPLE_ATTR_SIZE)
 234                count = SIMPLE_ATTR_SIZE - 1;
 235        error = copy_from_user(buffer->page,buf,count);
 236        buffer->needs_read_fill = 1;
 237        /* if buf is assumed to contain a string, terminate it by \0,
 238         * so e.g. sscanf() can scan the string easily */
 239        buffer->page[count] = 0;
 240        return error ? -EFAULT : count;
 241}
 242
 243static int
 244flush_write_buffer(struct file *file, struct configfs_buffer *buffer, size_t count)
 245{
 246        struct configfs_fragment *frag = to_frag(file);
 247        int res = -ENOENT;
 248
 249        down_read(&frag->frag_sem);
 250        if (!frag->frag_dead)
 251                res = buffer->attr->store(buffer->item, buffer->page, count);
 252        up_read(&frag->frag_sem);
 253        return res;
 254}
 255
 256
 257/**
 258 *      configfs_write_file - write an attribute.
 259 *      @file:  file pointer
 260 *      @buf:   data to write
 261 *      @count: number of bytes
 262 *      @ppos:  starting offset
 263 *
 264 *      Similar to configfs_read_file(), though working in the opposite direction.
 265 *      We allocate and fill the data from the user in fill_write_buffer(),
 266 *      then push it to the config_item in flush_write_buffer().
 267 *      There is no easy way for us to know if userspace is only doing a partial
 268 *      write, so we don't support them. We expect the entire buffer to come
 269 *      on the first write.
 270 *      Hint: if you're writing a value, first read the file, modify only the
 271 *      the value you're changing, then write entire buffer back.
 272 */
 273
 274static ssize_t
 275configfs_write_file(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
 276{
 277        struct configfs_buffer *buffer = file->private_data;
 278        ssize_t len;
 279
 280        mutex_lock(&buffer->mutex);
 281        len = fill_write_buffer(buffer, buf, count);
 282        if (len > 0)
 283                len = flush_write_buffer(file, buffer, len);
 284        if (len > 0)
 285                *ppos += len;
 286        mutex_unlock(&buffer->mutex);
 287        return len;
 288}
 289
 290/**
 291 *      configfs_write_bin_file - write a binary attribute.
 292 *      @file:  file pointer
 293 *      @buf:   data to write
 294 *      @count: number of bytes
 295 *      @ppos:  starting offset
 296 *
 297 *      Writing to a binary attribute file is similar to a normal read.
 298 *      We buffer the consecutive writes (binary attribute files do not
 299 *      support lseek) in a continuously growing buffer, but we don't
 300 *      commit until the close of the file.
 301 */
 302
 303static ssize_t
 304configfs_write_bin_file(struct file *file, const char __user *buf,
 305                        size_t count, loff_t *ppos)
 306{
 307        struct configfs_buffer *buffer = file->private_data;
 308        void *tbuf = NULL;
 309        ssize_t len;
 310
 311        mutex_lock(&buffer->mutex);
 312
 313        /* we don't support switching read/write modes */
 314        if (buffer->read_in_progress) {
 315                len = -ETXTBSY;
 316                goto out;
 317        }
 318        buffer->write_in_progress = true;
 319
 320        /* buffer grows? */
 321        if (*ppos + count > buffer->bin_buffer_size) {
 322
 323                if (buffer->cb_max_size &&
 324                        *ppos + count > buffer->cb_max_size) {
 325                        len = -EFBIG;
 326                        goto out;
 327                }
 328
 329                tbuf = vmalloc(*ppos + count);
 330                if (tbuf == NULL) {
 331                        len = -ENOMEM;
 332                        goto out;
 333                }
 334
 335                /* copy old contents */
 336                if (buffer->bin_buffer) {
 337                        memcpy(tbuf, buffer->bin_buffer,
 338                                buffer->bin_buffer_size);
 339                        vfree(buffer->bin_buffer);
 340                }
 341
 342                /* clear the new area */
 343                memset(tbuf + buffer->bin_buffer_size, 0,
 344                        *ppos + count - buffer->bin_buffer_size);
 345                buffer->bin_buffer = tbuf;
 346                buffer->bin_buffer_size = *ppos + count;
 347        }
 348
 349        len = simple_write_to_buffer(buffer->bin_buffer,
 350                        buffer->bin_buffer_size, ppos, buf, count);
 351out:
 352        mutex_unlock(&buffer->mutex);
 353        return len;
 354}
 355
 356static int __configfs_open_file(struct inode *inode, struct file *file, int type)
 357{
 358        struct dentry *dentry = file->f_path.dentry;
 359        struct configfs_fragment *frag = to_frag(file);
 360        struct configfs_attribute *attr;
 361        struct configfs_buffer *buffer;
 362        int error;
 363
 364        error = -ENOMEM;
 365        buffer = kzalloc(sizeof(struct configfs_buffer), GFP_KERNEL);
 366        if (!buffer)
 367                goto out;
 368
 369        error = -ENOENT;
 370        down_read(&frag->frag_sem);
 371        if (unlikely(frag->frag_dead))
 372                goto out_free_buffer;
 373
 374        error = -EINVAL;
 375        buffer->item = to_item(dentry->d_parent);
 376        if (!buffer->item)
 377                goto out_free_buffer;
 378
 379        attr = to_attr(dentry);
 380        if (!attr)
 381                goto out_put_item;
 382
 383        if (type & CONFIGFS_ITEM_BIN_ATTR) {
 384                buffer->bin_attr = to_bin_attr(dentry);
 385                buffer->cb_max_size = buffer->bin_attr->cb_max_size;
 386        } else {
 387                buffer->attr = attr;
 388        }
 389
 390        buffer->owner = attr->ca_owner;
 391        /* Grab the module reference for this attribute if we have one */
 392        error = -ENODEV;
 393        if (!try_module_get(buffer->owner))
 394                goto out_put_item;
 395
 396        error = -EACCES;
 397        if (!buffer->item->ci_type)
 398                goto out_put_module;
 399
 400        buffer->ops = buffer->item->ci_type->ct_item_ops;
 401
 402        /* File needs write support.
 403         * The inode's perms must say it's ok,
 404         * and we must have a store method.
 405         */
 406        if (file->f_mode & FMODE_WRITE) {
 407                if (!(inode->i_mode & S_IWUGO))
 408                        goto out_put_module;
 409                if ((type & CONFIGFS_ITEM_ATTR) && !attr->store)
 410                        goto out_put_module;
 411                if ((type & CONFIGFS_ITEM_BIN_ATTR) && !buffer->bin_attr->write)
 412                        goto out_put_module;
 413        }
 414
 415        /* File needs read support.
 416         * The inode's perms must say it's ok, and we there
 417         * must be a show method for it.
 418         */
 419        if (file->f_mode & FMODE_READ) {
 420                if (!(inode->i_mode & S_IRUGO))
 421                        goto out_put_module;
 422                if ((type & CONFIGFS_ITEM_ATTR) && !attr->show)
 423                        goto out_put_module;
 424                if ((type & CONFIGFS_ITEM_BIN_ATTR) && !buffer->bin_attr->read)
 425                        goto out_put_module;
 426        }
 427
 428        mutex_init(&buffer->mutex);
 429        buffer->needs_read_fill = 1;
 430        buffer->read_in_progress = false;
 431        buffer->write_in_progress = false;
 432        file->private_data = buffer;
 433        up_read(&frag->frag_sem);
 434        return 0;
 435
 436out_put_module:
 437        module_put(buffer->owner);
 438out_put_item:
 439        config_item_put(buffer->item);
 440out_free_buffer:
 441        up_read(&frag->frag_sem);
 442        kfree(buffer);
 443out:
 444        return error;
 445}
 446
 447static int configfs_release(struct inode *inode, struct file *filp)
 448{
 449        struct configfs_buffer *buffer = filp->private_data;
 450
 451        module_put(buffer->owner);
 452        if (buffer->page)
 453                free_page((unsigned long)buffer->page);
 454        mutex_destroy(&buffer->mutex);
 455        kfree(buffer);
 456        return 0;
 457}
 458
 459static int configfs_open_file(struct inode *inode, struct file *filp)
 460{
 461        return __configfs_open_file(inode, filp, CONFIGFS_ITEM_ATTR);
 462}
 463
 464static int configfs_open_bin_file(struct inode *inode, struct file *filp)
 465{
 466        return __configfs_open_file(inode, filp, CONFIGFS_ITEM_BIN_ATTR);
 467}
 468
 469static int configfs_release_bin_file(struct inode *inode, struct file *file)
 470{
 471        struct configfs_buffer *buffer = file->private_data;
 472
 473        buffer->read_in_progress = false;
 474
 475        if (buffer->write_in_progress) {
 476                struct configfs_fragment *frag = to_frag(file);
 477                buffer->write_in_progress = false;
 478
 479                down_read(&frag->frag_sem);
 480                if (!frag->frag_dead) {
 481                        /* result of ->release() is ignored */
 482                        buffer->bin_attr->write(buffer->item,
 483                                        buffer->bin_buffer,
 484                                        buffer->bin_buffer_size);
 485                }
 486                up_read(&frag->frag_sem);
 487                /* vfree on NULL is safe */
 488                vfree(buffer->bin_buffer);
 489                buffer->bin_buffer = NULL;
 490                buffer->bin_buffer_size = 0;
 491                buffer->needs_read_fill = 1;
 492        }
 493
 494        configfs_release(inode, file);
 495        return 0;
 496}
 497
 498
 499const struct file_operations configfs_file_operations = {
 500        .read           = configfs_read_file,
 501        .write          = configfs_write_file,
 502        .llseek         = generic_file_llseek,
 503        .open           = configfs_open_file,
 504        .release        = configfs_release,
 505};
 506
 507const struct file_operations configfs_bin_file_operations = {
 508        .read           = configfs_read_bin_file,
 509        .write          = configfs_write_bin_file,
 510        .llseek         = NULL,         /* bin file is not seekable */
 511        .open           = configfs_open_bin_file,
 512        .release        = configfs_release_bin_file,
 513};
 514
 515/**
 516 *      configfs_create_file - create an attribute file for an item.
 517 *      @item:  item we're creating for.
 518 *      @attr:  atrribute descriptor.
 519 */
 520
 521int configfs_create_file(struct config_item * item, const struct configfs_attribute * attr)
 522{
 523        struct dentry *dir = item->ci_dentry;
 524        struct configfs_dirent *parent_sd = dir->d_fsdata;
 525        umode_t mode = (attr->ca_mode & S_IALLUGO) | S_IFREG;
 526        int error = 0;
 527
 528        inode_lock_nested(d_inode(dir), I_MUTEX_NORMAL);
 529        error = configfs_make_dirent(parent_sd, NULL, (void *) attr, mode,
 530                                     CONFIGFS_ITEM_ATTR, parent_sd->s_frag);
 531        inode_unlock(d_inode(dir));
 532
 533        return error;
 534}
 535
 536/**
 537 *      configfs_create_bin_file - create a binary attribute file for an item.
 538 *      @item:  item we're creating for.
 539 *      @attr:  atrribute descriptor.
 540 */
 541
 542int configfs_create_bin_file(struct config_item *item,
 543                const struct configfs_bin_attribute *bin_attr)
 544{
 545        struct dentry *dir = item->ci_dentry;
 546        struct configfs_dirent *parent_sd = dir->d_fsdata;
 547        umode_t mode = (bin_attr->cb_attr.ca_mode & S_IALLUGO) | S_IFREG;
 548        int error = 0;
 549
 550        inode_lock_nested(dir->d_inode, I_MUTEX_NORMAL);
 551        error = configfs_make_dirent(parent_sd, NULL, (void *) bin_attr, mode,
 552                                     CONFIGFS_ITEM_BIN_ATTR, parent_sd->s_frag);
 553        inode_unlock(dir->d_inode);
 554
 555        return error;
 556}
 557